抖音只能上下滑动吗_仿抖音上下滑动播放视频

太多朋友对短视频,上下滚动播放视频效果比较比较研究,今天看看这个案例。

讲下大概思路,使用Recycleview配合自定义LinearLayoutManager来实现这个功能,这里着重说下自定义LinearLayoutManager的实现可以看到每当下一个项目滑入屏幕时,上面的项目会继续播放视频,而滑入的项目只有当全部进入屏幕才会播放,而且当手指抬起时,当前item会根据滑动的距离相应的自动滑入滑出,针对这种情况,就会想到使用SnapHelper

RecyclerView在24.2.0版本中新增了SnapHelper这个辅助类,利用辅助RecyclerView在滚动结束时将项目对准到某个位置。特别是列表横向滑动时,很多时候不会让列表滑到任意位置,甚至会有一定的规则限制,这时候就可以通过SnapHelper来定义对齐规则了。

SnapHelper是一个抽象类,官方提供了一个LinearSnapHelper的子类,可以让RecyclerView滚动停止时相应的项保持中间位置。25.1.0版本中官方又提供了一个PagerSnapHelper的子类,可以使RecyclerView像ViewPager一样效果,一次只能滑动一页,而且居中显示,直接使用SnapHelper可以帮助RecyclerView滑动完成后进行对齐操作,让item的侧边对齐或者居中对齐,这样实现上下滑动进行视频切换。这里有SnapHelper的详解

2,正式撸代码:1。首先定义一个接口,用于执行item的相关操作

公共接口OnViewPagerListener {

/ * 初始化完成* /

void onInitComplete();

/ *释放的监听器* /

void onPageRelease(boolean isNext,int position);

/ *的监听器以及判断是否可以滑动到底部* /

void onPageSelected(int position,boolean isBottom);

} ```

2.继承LinearLayoutManager,对滑入滑出的项目某些1中接口里面的方法

导入android.content.Context; 导入android.support.annotation.NonNull; 导入android.support.v7.widget.LinearLayoutManager; 导入android.support.v7.widget.PagerSnapHelper; 导入android.support.v7.widget.RecyclerView; 导入android.view.View;

公共类MyLayoutManager扩展LinearLayoutManager实现RecyclerView.OnChildAttachStateChangeListener {private int mDrift;//位移,用于判断移动方向的专有PagerSnapHelper mPagerSnapHelper;私人OnViewPagerListener mOnViewPagerListener;公共MyLayoutManager(上下文上下文){super(context);} public MyLayoutManager(上下文上下文,int方向,布尔反向布局){超级(上下文,方向,reverseLayout);mPagerSnapHelper = new PagerSnapHelper();} @覆盖公共无效onAttachedToWindow(RecyclerView视图){view.addOnChildAttachStateChangeListener(本);

mPagerSnapHelper.attachToRecyclerView(view);

super.onAttachedToWindow(view);

}

//当项目添加进来了调用这个方法// @覆盖公共无效onChildViewAttachedToWindow(@NonNull查看视图){

//播放视频操作即将要播放的是上一个视频还是下一个视频int position = getPosition(view);if(0 ==位置){if(mOnViewPagerListener!= null){mOnViewPagerListener.onPageSelected(getPosition(view),false);}}}} public void setOnViewPagerListener(OnViewPagerListener mOnViewPagerListener){this.mOnViewPagerListener = mOnViewPagerListener;} @覆盖公共无效onScrollStateChanged(INT状态){开关(状态){情况下RecyclerView.SCROLL_STATE_IDLE:Viewview = mPagerSnapHelper.findSnapView(本); int position = getPosition(view);如果(mOnViewPagerListener!= null){mOnViewPagerListener.onPageSelected(position,position == getItemCount()-1);}

//位置—部分----》播放break;} super.onScrollStateChanged(状态);} @覆盖公共无效onChildViewDetachedFromWindow(@NonNull视图视图){

//暂停播放操作

if(mDrift> = 0){

if(mOnViewPagerListener!= null)

mOnViewPagerListener.onPageRelease(true,getPosition(view));

} else {

如果(mOnViewPagerListener!= null)

mOnViewPagerListener.onPageRelease(false,getPosition(view));

}

}

@Override

public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {

this.mDrift = dy;

return super.scrollVerticallyBy(dy, recycler, state);

}

@Override

public boolean canScrollVertically() {

return true;

}

}

3.接下来就是正常使用recycleview了 配合原生VideoView 播放视频,切换时先用一张截图盖住视频,视频渲染成功再隐藏截图,感觉上是无缝切换(这里是原生播放器初始加载视频会黑屏,如果用更高级的播放器可能不会有这个问题)

导入android.annotation.TargetApi; 导入android.content.Context; 导入android.media.MediaPlayer; 导入android.net.Uri; 导入android.os.Build; 导入android.os.Bundle; 导入android.support.v7.app.AppCompatActivity; 导入android.support.v7.widget.OrientationHelper; 导入android.support.v7.widget.RecyclerView; 导入android.util.Log; 导入android.view.LayoutInflater; 导入android.view.View; 导入android.view.ViewGroup; 导入android.widget.ImageView; 导入android.widget.RelativeLayout; 导入android.widget.VideoView;

公共类MainActivity扩展了AppCompatActivity {private static final String TAG =“ douyin”; 私人RecyclerView mRecyclerView; 私有MyAdapter mAdapter; MyLayoutManager2 myLayoutManager; @Override protected void onCreate(捆绑的saveInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initListener();}私有无效initView(){mRecyclerView = findViewById(R.id.recycler);myLayoutManager = new MyLayoutManager2(this,OrientationHelper.VERTICAL,false);mAdapter =新的MyAdapter(this); mRecyclerView.setLayoutManager(myLayoutManager); mRecyclerView.setAdapter(mAdapter); } private void initListener(){

myLayoutManager.setOnViewPagerListener(new OnViewPagerListener() {

@Override

public void onInitComplete() {

}

@覆盖

公共无效onPageRelease(布尔isNext,INT位置){

Log.e(TAG, “释放位置:” +位置+ “下一页:” + isNext);

int索引= 0;

如果(isNext){

索引= 0;

} else {

index = 1;

}

releaseVideo(index);

}

@覆盖

公共无效使用onPageSelected(INT位置,布尔底部){

Log.e(TAG, “选择位置:” +位置+ “下一页:” +底部);

playVideo(0);

}

});

}

class MyAdapter extends RecyclerView.Adapter {

private int[] imgs = {R.mipmap.img_video_1, R.mipmap.img_video_2, R.mipmap.img_video_3, R.mipmap.img_video_4, R.mipmap.img_video_5, R.mipmap.img_video_6, R.mipmap.img_video_7, R.mipmap.img_video_8};

private int[] videos = {R.raw.video_1, R.raw.video_2, R.raw.video_3, R.raw.video_4, R.raw.video_5, R.raw.video_6, R.raw.video_7, R.raw.video_8};

private int index = 0;

private Context mContext;

public MyAdapter(Context context) {

this.mContext = context;

}

@Override

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_pager, parent, false);

return new ViewHolder(view);

}

@Override

public void onBindViewHolder(ViewHolder holder, int position) {

holder.img_thumb.setImageResource(imgs[index]);

holder.videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + videos[index]));

index++;

if (index >= 7) {

index = 0;

}

}

@Override

public int getItemCount() {

return 88;

}

public class ViewHolder extends RecyclerView.ViewHolder {

ImageView img_thumb;

VideoView videoView;

ImageView img_play;

RelativeLayout rootView;

公共ViewHolder(查看itemView){

超级(itemView);

img_thumb = itemView.findViewById(R.id.img_thumb);

videoView = itemView.findViewById(R.id.video_view);

img_play = itemView.findViewById(R.id.img_play);

rootView = itemView.findViewById(R.id.root_view);

}

}

}

private void releaseVideo(int索引){

查看itemView = mRecyclerView.getChildAt(索引);

最终VideoView videoView = itemView.findViewById(R.id.video_view);

最终的ImageView imgThumb = itemView.findViewById(R.id.img_thumb);

最终的ImageView imgPlay = itemView.findViewById(R.id.img_play);

videoView.stopPlayback();

imgThumb.animate()。alpha(1)

.start ();imgPlay.animate()。alpha(0f) .start();

}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)私有无效playVideo(int position){查看itemView = mRecyclerView.getChildAt(position);最终FullWindowVideoView videoView = itemView.findViewById(R.id.video_view);最终的ImageView imgPlay = itemView.findViewById(R.id.img_play); 最终的ImageView imgThumb = itemView.findViewById(R.id.img_thumb); 最终RelativeLayout rootView = itemView.findViewById(R.id.root_view);最终的MediaPlayer [] mediaPlayer =新的MediaPlayer [1]; videoView.setOnPreparedListener(新MediaPlayer.OnPreparedListener(){ @ 覆盖公共无效onPrepared(MediaPlayer的熔点){ } }); videoView.setOnInfoListener(新MediaPlayer.OnInfoListener(){ @

覆盖公共布尔onInfo(MediaPlayer的浓度,INT,整型附加){

MEDIAPLAYER [0] =熔点;

mp.setLooping(真)

。imgThumb.animate()α(0).setDuration(200)。开始();

返回假

}

});

videoView.start();

imgPlay.setOnClickListener(新View.OnClickListener(){

boolean isPlaying = true;)。)。 )。))))))))))))))))。)

@覆盖

公共无效的onClick(查看v){

如果(videoView.isPlaying()){

imgPlay.animate()α(0.7F) 。

;;;; videoView .pause();

IsPlaying模块= FALSE;

}其他{

imgPlay.animate()。alpha(0f)

.start(); videoView.start();

isPlaying = true;

}

}

} ;;

}}”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值