本文主要介绍采用RecyclerVIEw配合PagerSnapHelper实现短视频滑动播放内容。
1. 主页内容构建主页布局文件定义RecyclerVIEw,为RecyclerVIEw建立对应适配器。
<androIDx.recyclervIEw.Widget.RecyclerVIEw androID:ID="@+ID/rv_little_vIDeo" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" />
适配器条目中添加视频播放容器FrameLayout及封面ImageVIEw.
<FrameLayout androID:ID="@+ID/fl_content_item" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:background="@androID:color/black"><ImageVIEw androID:ID="@+ID/iv_thumb_item" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:scaleType="centerCrop" /></FrameLayout>
2.定义RecyclerVIEw滑动管理PagerSnapHelper 结合 linearlayoutmanager 实现滑动管理,实现监听任务。
PagerSnapHelper介绍PagerSnapHelper can help achIEve a similar behavior to
VIEwPager. Set both RecyclerVIEw and the items of the RecyclerVIEw.Adapter to have androID.vIEw.VIEwGroup.LayoutParams#MATCH_PARENT height and wIDth and then attach PagerSnapHelper to the RecyclerVIEw using #attachToRecyclerVIEw(RecyclerVIEw)}.
翻译:PagerSnapHelper可以帮助实现与以下类似的行为
VIEwPager。 将RecyclerVIEw和RecyclerVIEw.Adapter的项目都设置为具有androID.vIEw.VIEwGroup.LayoutParams#MATCH_PARENT的高度和宽度,然后使用#attachToRecyclerVIEw(RecyclerVIEw)}将PagerSnapHelper附加到RecyclerVIEw。
自定义RecyclerVIEw管理器
RecyclerVIEw管理器为linearlayoutmanager 时,默认为纵向滑动,如果想采用横向滑动,就设置其滑动方向为RecyclerVIEw.HORIZONTAL。同理,我们也可以这样采用setorIEntation(RecyclerVIEw.HORIZONTAL) 方法去改变滑动方向。
public class PagerLayoutManager extends linearlayoutmanager implements RecyclerVIEw.OnChildAttachStatechangelistener { private OnPageChangedListener mOnPageChangedListener; private PagerSnapHelper mSnapHelper; /** * 移动方向标记 */ private int direction; public PagerLayoutManager(Context context) { super(context); mSnapHelper = new PagerSnapHelper(); } /** * PagerSnapHelper绑定RecyclerVIEw,同时为监听RecyclerVIEw子布局附着,脱离,进行滑动页面内容控制 * * @param vIEw RecyclerVIEw */ @OverrIDe public voID onAttachedToWindow(RecyclerVIEw vIEw) { super.onAttachedToWindow(vIEw); mSnapHelper.attachToRecyclerVIEw(vIEw); vIEw.addOnChildAttachStatechangelistener(this); } /** * 滑动状态改变监听,滑动完毕后进行播放控制 * * @param state 滑动状态 */ @OverrIDe public voID onScrollStateChanged(int state) { super.onScrollStateChanged(state); if (state == RecyclerVIEw.SCRolL_STATE_IDLE) { VIEw vIEw = mSnapHelper.findSnapVIEw(this); if (vIEw == null) { return; } int position = getposition(vIEw); if (mOnPageChangedListener != null && getChildCount() == 1) { mOnPageChangedListener.onPageSelected(position, position == getItemCount() - 1); } } } @OverrIDe public int scrollHorizontallyBy(int dx, RecyclerVIEw.Recycler recycler, RecyclerVIEw.State state) { direction = dx; return super.scrollHorizontallyBy(dx, recycler, state); } @OverrIDe public int scrollVerticallyBy(int dy, RecyclerVIEw.Recycler recycler, RecyclerVIEw.State state) { direction = dy; return super.scrollVerticallyBy(dy, recycler, state); } @OverrIDe public voID onChildVIEwAttachedToWindow(@NonNull VIEw vIEw) { if (mOnPageChangedListener != null && getChildCount() == 1) { mOnPageChangedListener.onPageInitComplete(); } } @OverrIDe public voID onChildVIEwDetachedFromWindow(@NonNull VIEw vIEw) { if (mOnPageChangedListener != null) { mOnPageChangedListener.onPageRelease(getposition(vIEw), direction >= 0); } } public voID setonPageChangedListener(OnPageChangedListener mOnPageChangedListener) { this.mOnPageChangedListener = mOnPageChangedListener; } public interface OnPageChangedListener { /** * 初始化子布局加载完成 */ voID onPageInitComplete(); /** * 子布局脱离 * * @param position 子布局在RecyclerVIEw位置 * @param isNext 是否有下一个 */ voID onPageRelease(int position, boolean isNext); /** * 子布局附着 * * @param position 子布局在RecyclerVIEw位置 * @param isLast 是否最后一个 */ voID onPageSelected(int position, boolean isLast); }}
3. 视频滑动实现为RecyclerVIEw 设置管理器PagerLayoutManager,设置其Adapter数据内容,进行封面展示,且此时会回调onPageInitComplete()方法,进行首个视频播放。对RecyclerVIEw进行滑动,当页面滑动结束后,会先回调管理器中onPageRelease()方法,此时可对进行中播放器进行停止释放;然后,回调onPageSelected()方法,对选中页面内容进行展示播放。
当滑动后取消时,要进行判断当前位置,避免当前页视频停止或重复播放。
mPagerLayoutManager = new PagerLayoutManager(this);mPagerLayoutManager.setonPageChangedListener(new PagerLayoutManager.OnPageChangedListener() {@OverrIDepublic voID onPageInitComplete() { int position = mPagerLayoutManager.findFirstVisibleItemposition(); if (position != -1) { mCurrentposition = position; } startPlay(mCurrentposition);}@OverrIDepublic voID onPageRelease(int position, boolean isNext) { if (mCurrentposition == position) { stopPlay(); BaseVIEwHolder vIEwHolder = (BaseVIEwHolder) mRvlittleVIDeo.findVIEwHolderForLayoutposition(mCurrentposition); if (vIEwHolder != null) { ImageVIEw mVIDeoThumb = vIEwHolder.getVIEw(R.ID.iv_thumb_item); if (mVIDeoThumb != null) { mVIDeoThumb.setVisibility(VIEw.VISIBLE); } } }}@OverrIDepublic voID onPageSelected(int position, boolean isLast) { if (mCurrentposition == position) { return; } startPlay(position); mCurrentposition = position; }});mRvlittleVIDeo.setLayoutManager(mPagerLayoutManager);mlittleVIDeoAdapter = new littleVIDeoAdapter();mRvlittleVIDeo.setAdapter(mlittleVIDeoAdapter);
3. 播放器初始化及停止、播放初始化播放器内容
private voID initVIDeo() { mVIDeoVIEw = new littleVIDeoVIEw(this); GSYVIDeoType.setShowType(GSYVIDeoType.SCREEN_TYPE_FulL); mGsySmallVIDeoHelperBuilder = new GSYVIDeoOptionBuilder(); mGsySmallVIDeoHelperBuilder .setLooPing(true) .setCacheWithPlay(true) .setIstouchWiget(false) .setVIDeoAllCallBack(new GSYSampleCallBack() { @OverrIDe public voID onPrepared(String url, Object... objects) { super.onPrepared(url, objects); new Handler().postDelayed(new Runnable() { @OverrIDe public voID run() { BaseVIEwHolder vIEwHolder = (BaseVIEwHolder) mRvlittleVIDeo.findVIEwHolderForLayoutposition(mCurrentposition); if (vIEwHolder != null) { ImageVIEw mVIDeoThumb = vIEwHolder.getVIEw(R.ID.iv_thumb_item); if (mVIDeoThumb != null) { mVIDeoThumb.setVisibility(VIEw.INVISIBLE); } } } }, 100); } });}
开始播放视频内容,进行播放器视图加载
private voID startPlay(int position) { if (position < 0 || position >= mlittleVIDeoAdapter.getData().size()) { return; } BaseVIEwHolder holder = (BaseVIEwHolder) mRvlittleVIDeo.findVIEwHolderForLayoutposition(position); VIEwParent parent = mVIDeoVIEw.getParent(); if (parent instanceof FrameLayout) { ((VIEwGroup) parent).removeVIEw(mVIDeoVIEw); } if (holder != null) { FrameLayout mVIDeoContent = holder.getVIEw(R.ID.fl_content_item); mVIDeoContent.addVIEw(mVIDeoVIEw, 0); mGsySmallVIDeoHelperBuilder.setUrl(mlittleVIDeoAdapter.getData().get(position).getUrl()); mGsySmallVIDeoHelperBuilder.build(mVIDeoVIEw); mVIDeoVIEw.startPlayLogic(); }}
停止播放,移除视图
private voID stopPlay() { mVIDeoVIEw.release(); VIEwParent parent = mVIDeoVIEw.getParent(); if (parent instanceof FrameLayout) { ((FrameLayout) parent).removeVIEw(mVIDeoVIEw); }}
3. 播放器内容例子中采用了自定义空布局的播放器继承自GSY开源播放器,单纯进行视频播放,当然也可以采用其它的播放器饺子或者IjkPlayer等。
public class littleVIDeoVIEw extends StandardGSYVIDeoPlayer { public littleVIDeoVIEw(Context context, Boolean fullFlag) { super(context, fullFlag); } public littleVIDeoVIEw(Context context) { super(context); } public littleVIDeoVIEw(Context context, AttributeSet attrs) { super(context, attrs); } @OverrIDe public int getLayoutID() { return R.layout.empty_control_vIDeo; }}
布局文件
<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:background="@androID:color/black"> <FrameLayout androID:ID="@+ID/surface_container" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:gravity="center"> </FrameLayout></relativeLayout>
简单的滑动播放这些就完成了,例子也只是仅仅提供了实现的方法和思路,供大家进行学习参考,实际使用中可以对其进一步地进行封装及处理,接下来也会补充一些滑动播放适配器的数据加载处理以及多布局内容展示等内容。
Android短视频滑动播放(二)
关注公众号:几圈年轮,查看更多有趣的技术、工具、闲言、资源。
总结以上是内存溢出为你收集整理的Android短视频滑动播放(一)全部内容,希望文章能够帮你解决Android短视频滑动播放(一)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)