不少朋友对短视频,上下滑动播放视频效果比较比较感兴趣,今天看看这个案例。
1、效果图:
讲下大概思路,使用RecyclevIEw配合自定义linearlayoutmanager来实现这个功能,这里着重说下自定义linearlayoutmanager的实现可以看到每当下一个item滑入屏幕时,上面的item会继续播放视频,而滑入的item只有当全部进入屏幕才会播放,而且当手指抬起时,当前item会根据滑动的距离相应的自动滑入滑出,针对这种情形,就会想到使用SnapHelper
RecyclerVIEw在24.2.0版本中新增了SnapHelper这个辅助类,用于辅助RecyclerVIEw在滚动结束时将Item对齐到某个位置。特别是列表横向滑动时,很多时候不会让列表滑到任意位置,而是会有一定的规则限制,这时候就可以通过SnapHelper来定义对齐规则了。
SnapHelper是一个抽象类,官方提供了一个linearSnapHelper的子类,可以让RecyclerVIEw滚动停止时相应的Item停留中间位置。25.1.0版本中官方又提供了一个PagerSnapHelper的子类,可以使RecyclerVIEw像VIEwPager一样的效果,一次只能滑一页,而且居中显示,也就是说使用SnapHelper可以帮助RecyclerVIEw滑动完成后进行对齐 *** 作,让item的侧边对齐或者居中对齐,这样实现上下滑动进行视频切换。这里有SnapHelper的详解
2、正式撸代码:
1.首先定义一个接口,用来执行item的相关 *** 作
public interface OnVIEwPagerListener { /*初始化完成*/ voID onInitComplete(); /*释放的监听*/ voID onPageRelease(boolean isNext, int position); /*选中的监听以及判断是否滑动到底部*/ voID onPageSelected(int position, boolean isBottom);}
2.继承linearlayoutmanager ,对滑入滑出的item回调1中接口里面的方法
import androID.content.Context;import androID.support.annotation.NonNull;import androID.support.v7.Widget.linearlayoutmanager;import androID.support.v7.Widget.PagerSnapHelper;import androID.support.v7.Widget.RecyclerVIEw;import androID.vIEw.VIEw;public class MyLayoutManager extends linearlayoutmanager implements RecyclerVIEw.OnChildAttachStatechangelistener { private int mDrift;//位移,用来判断移动方向 private PagerSnapHelper mPagerSnapHelper; private OnVIEwPagerListener mOnVIEwPagerListener; public MyLayoutManager(Context context) { super(context); } public MyLayoutManager(Context context, int orIEntation, boolean reverseLayout) { super(context, orIEntation, reverseLayout); mPagerSnapHelper = new PagerSnapHelper(); } @OverrIDe public voID onAttachedToWindow(RecyclerVIEw vIEw) { vIEw.addOnChildAttachStatechangelistener(this); mPagerSnapHelper.attachToRecyclerVIEw(vIEw); super.onAttachedToWindow(vIEw); }//当Item添加进来了 调用这个方法 // @OverrIDe public voID onChildVIEwAttachedToWindow(@NonNull VIEw vIEw) {// 播放视频 *** 作 即将要播放的是上一个视频 还是下一个视频 int position = getposition(vIEw); if (0 == position) { if (mOnVIEwPagerListener != null) { mOnVIEwPagerListener.onPageSelected(getposition(vIEw), false); } } } public voID setonVIEwPagerListener(OnVIEwPagerListener mOnVIEwPagerListener) { this.mOnVIEwPagerListener = mOnVIEwPagerListener; } @OverrIDe public voID onScrollStateChanged(int state) { switch (state) { case RecyclerVIEw.SCRolL_STATE_IDLE: VIEw vIEw = mPagerSnapHelper.findSnapVIEw(this); int position = getposition(vIEw); if (mOnVIEwPagerListener != null) { mOnVIEwPagerListener.onPageSelected(position, position == getItemCount() - 1); }// postion ---回调 ----》播放 break; } super.onScrollStateChanged(state); } @OverrIDe public voID onChildVIEwDetachedFromWindow(@NonNull VIEw vIEw) {//暂停播放 *** 作 if (mDrift >= 0) { if (mOnVIEwPagerListener != null) mOnVIEwPagerListener.onPageRelease(true, getposition(vIEw)); } else { if (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 播放视频,切换时先用一张截图盖住视频,视频渲染成功再隐藏截图,感觉上是无缝切换(这里是原生播放器初始加载视频会黑屏,如果用更高级的播放器可能不会有这个问题)
import androID.annotation.TargetAPI;import androID.content.Context;import androID.media.MediaPlayer;import androID.net.Uri;import androID.os.Build;import androID.os.Bundle;import androID.support.v7.app.AppCompatActivity;import androID.support.v7.Widget.OrIEntationHelper;import androID.support.v7.Widget.RecyclerVIEw;import androID.util.Log;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.ImageVIEw;import androID.Widget.relativeLayout;import androID.Widget.VIDeoVIEw;public class MainActivity extends AppCompatActivity { private static final String TAG = "douyin"; private RecyclerVIEw mRecyclerVIEw; private MyAdapter mAdapter; MyLayoutManager2 myLayoutManager; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); initVIEw(); initListener(); } private voID initVIEw() { mRecyclerVIEw = findVIEwByID(R.ID.recycler); myLayoutManager = new MyLayoutManager2(this, OrIEntationHelper.VERTICAL, false); mAdapter = new MyAdapter(this); mRecyclerVIEw.setLayoutManager(myLayoutManager); mRecyclerVIEw.setAdapter(mAdapter); } private voID initListener() { myLayoutManager.setonVIEwPagerListener(new OnVIEwPagerListener() { @OverrIDe public voID onInitComplete() { } @OverrIDe public voID onPageRelease(boolean isNext, int position) { Log.e(TAG, "释放位置:" + position + " 下一页:" + isNext); int index = 0; if (isNext) { index = 0; } else { index = 1; } releaseVIDeo(index); } @OverrIDe public voID onPageSelected(int position, boolean bottom) { Log.e(TAG, "选择位置:" + position + " 下一页:" + bottom); playVIDeo(0); } }); } class MyAdapter extends RecyclerVIEw.Adapter<MyAdapter.VIEwHolder> { 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; public VIEwHolder(VIEw itemVIEw) { super(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 index) { VIEw itemVIEw = mRecyclerVIEw.getChildAt(index); final VIDeoVIEw vIDeoVIEw = itemVIEw.findVIEwByID(R.ID.vIDeo_vIEw); final ImageVIEw imgThumb = itemVIEw.findVIEwByID(R.ID.img_thumb); final 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) private voID playVIDeo(int position) { VIEw itemVIEw = mRecyclerVIEw.getChildAt(position); final FullWindowVIDeoVIEw vIDeoVIEw = itemVIEw.findVIEwByID(R.ID.vIDeo_vIEw); final ImageVIEw imgPlay = itemVIEw.findVIEwByID(R.ID.img_play); final ImageVIEw imgThumb = itemVIEw.findVIEwByID(R.ID.img_thumb); final relativeLayout rootVIEw = itemVIEw.findVIEwByID(R.ID.root_vIEw); final MediaPlayer[] mediaPlayer = new MediaPlayer[1]; vIDeoVIEw.setonPreparedListener(new MediaPlayer.OnPreparedListener() { @OverrIDe public voID onPrepared(MediaPlayer mp) { } }); vIDeoVIEw.setonInfoListener(new MediaPlayer.OnInfoListener() { @OverrIDe public boolean onInfo(MediaPlayer mp, int what, int extra) { mediaPlayer[0] = mp; mp.setLooPing(true); imgThumb.animate().Alpha(0).setDuration(200).start(); return false; } }); vIDeoVIEw.start(); imgPlay.setonClickListener(new VIEw.OnClickListener() { boolean isPlaying = true; @OverrIDe public voID onClick(VIEw v) { if (vIDeoVIEw.isPlaying()) { imgPlay.animate().Alpha(0.7f).start(); vIDeoVIEw.pause(); isPlaying = false; } else { imgPlay.animate().Alpha(0f).start(); vIDeoVIEw.start(); isPlaying = true; } } }); }}
原创作者:庞哈哈哈12138,原文:https://www.jianshu.com/p/3a043cd4eb1f
欢迎关注我的微信公众号「码农突围」,分享Python、Java、大数据、机器学习、人工智能等技术,关注码农技术提升•职场突围•思维跃迁,20万+码农成长充电第一站,陪有梦想的你一起成长。
总结以上是内存溢出为你收集整理的仿抖音上下滑动播放视频全部内容,希望文章能够帮你解决仿抖音上下滑动播放视频所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)