Android Recyclerview列表自动播放视频
来源:互联网 发布:底盘装甲 知乎 编辑:程序博客网 时间:2024/06/08 14:13
前言:最近项目比较忙很久没写博客了,一个月迭代了三个版本也是醉了。。。谁叫我们是苦逼的程序猿呢,回归正传;最近主要在弄一个跟视频有关的项目,里面也学到一些东西,现在记录一下;其中一个是仿微博的视频列表自动播放功能,具体可以看下图:
项目中视频使用的是GSYVideoPlayer 这个开源库。
ps:作者很热心,nice。
废话不多说,直接进入重点;既然要实现类似微博那种滚动列表时,处于当前屏幕的项自动播放,那么肯定得监听列表的滚动事件,好在Recyclerview中给我们提供了接口:
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); switch (newState) { case SCROLL_STATE_IDLE: //滚动停止 break; case SCROLL_STATE_DRAGGING: //手指拖动 break; case SCROLL_STATE_SETTLING: //惯性滚动 break; } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); } });
如上onScrollStateChanged 方法 给我们返回了三种状态:
SCROLL_STATE_DRAGGING: 手指按住屏幕拖动
SCROLL_STATE_SETTLING: 手指快速在屏幕滑一下后的惯性滑动
SCROLL_STATE_IDLE: 屏幕处于禁止状态
而onScrolled 方法给我们返回了 dx:水平滚动距离、dy:垂直滚动距离。这两个值都是用手指开始触摸的位置减去移动后的位置,所以:
dx > 0 时为手指向左滚动,列表滚动显示右面的内容
dx < 0 时为手指向右滚动,列表滚动显示左面的内容
dy > 0 时为手指向上滚动,列表滚动显示下面的内容
dy < 0 时为手指向下滚动,列表滚动显示上面的内容
项目中暂时没用到这些,但是这些值很有用。
在这个方法中我们需要获取三个值:
(1) 在屏幕可见区域的第一项位置 - 通过findFirstVisibleItemPosition()
方法获取
(2) 在屏幕可见区域的最后一项位置 - 通过findLastVisibleItemPosition()
方法获取
(3)屏幕可见项的数目 - 用(2)减去(1)即可
为什么需要以上值,这里说下整体思路:
(1)获取当前处于屏幕可见的列表
(2)滑出屏幕的视频我们需要回收掉
(3)当屏幕处于静止状态时我们才开始播放视频
第一点:获取可见列表;上面获取的三个值已经解决了,直接看代码:
public int firstVisibleItem, lastVisibleItem, visibleCount; @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); firstVisibleItem = layoutManager.findFirstVisibleItemPosition(); lastVisibleItem = layoutManager.findLastVisibleItemPosition(); visibleCount = lastVisibleItem - firstVisibleItem; }
第二点:回收滑出屏幕的视频,获取到当前播放的位置(开源库中有相关方法)判断是否在屏幕可见,不可见就回收;具体看代码
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); //大于0说明有播放 if (GSYVideoManager.instance().getPlayPosition() >= 0) { //当前播放的位置 int position = GSYVideoManager.instance().getPlayPosition(); //对应的播放列表TAG if (GSYVideoManager.instance().getPlayTag().equals(HomeAdapter.TAG) && (position < firstVisibleItem || position > lastVisibleItem)) { GSYVideoManager.releaseAllVideos(); } } }
第三点:屏幕处于静止时才开始播放,只要播放的逻辑写在onScrollStateChanged
的 SCROLL_STATE_IDLE
状态下即可;
@Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); switch (newState) { case SCROLL_STATE_IDLE: //滚动停止 autoPlayVideo(recyclerView); break; } }void autoPlayVideo(RecyclerView view) { for (int i = 0; i < visibleCount; i++) { if (view != null && view.getChildAt(i) != null && view.getChildAt(i).findViewById(R.id.video_item_player) != null) { HomeGSYVideoPlayer homeGSYVideoPlayer = (HomeGSYVideoPlayer) view.getChildAt(i).findViewById(R.id.video_item_player); Rect rect = new Rect(); homeGSYVideoPlayer.getLocalVisibleRect(rect); int videoheight = homeGSYVideoPlayer.getHeight(); if (rect.top == 0 && rect.bottom == videoheight) { if (homeGSYVideoPlayer.getCurrentState() == homeGSYVideoPlayer.CURRENT_STATE_NORMAL || homeGSYVideoPlayer.getCurrentState() == homeGSYVideoPlayer.CURRENT_STATE_ERROR) { homeGSYVideoPlayer.getStartButton().performClick(); } return; } } } GSYVideoPlayer.releaseAllVideos(); }
autoPlayVideo方法里面就是通过 循环遍历 可见区域的播放器 然后通过 getLocalVisibleRect(rect)
方法计算出谁完全显示出来,对应方法可以查看getLocalVisibleRect 写的很详细。最后判断如果播放器处于可播放的状态即调用start按钮播放。
因为是公司代码,所以很多地方不能开放出来,忘见谅。最后附上主要完整代码:
public int firstVisibleItem, lastVisibleItem, visibleCount; public void loadListener() { mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { boolean scrollState = false; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); switch (newState) { case SCROLL_STATE_IDLE: //滚动停止 scrollState = false;// autoPlayVideo(recyclerView); break; case SCROLL_STATE_DRAGGING: //手指拖动 scrollState = true; break; case SCROLL_STATE_SETTLING: //惯性滚动 scrollState = true; break; } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); firstVisibleItem = layoutManager.findFirstVisibleItemPosition(); lastVisibleItem = layoutManager.findLastVisibleItemPosition(); visibleCount = lastVisibleItem - firstVisibleItem; //大于0说明有播放 if (GSYVideoManager.instance().getPlayPosition() >= 0) { //当前播放的位置 int position = GSYVideoManager.instance().getPlayPosition(); //对应的播放列表TAG if (GSYVideoManager.instance().getPlayTag().equals(HomeAdapter.TAG) && (position < firstVisibleItem || position > lastVisibleItem)) { GSYVideoManager.onPause(); } } } }); } private void autoPlayVideo(RecyclerView view) { for (int i = 0; i < visibleCount; i++) { if (view != null && view.getChildAt(i) != null && view.getChildAt(i).findViewById(R.id.video_item_player) != null) { HomeGSYVideoPlayer homeGSYVideoPlayer = (HomeGSYVideoPlayer) view.getChildAt(i).findViewById(R.id.video_item_player); Rect rect = new Rect(); homeGSYVideoPlayer.getLocalVisibleRect(rect); int videoheight = homeGSYVideoPlayer.getHeight(); if (rect.top == 0 && rect.bottom == videoheight) { if (homeGSYVideoPlayer.getCurrentState() == homeGSYVideoPlayer.CURRENT_STATE_NORMAL || homeGSYVideoPlayer.getCurrentState() == homeGSYVideoPlayer.CURRENT_STATE_ERROR) { homeGSYVideoPlayer.getStartButton().performClick(); } return; } } } GSYVideoPlayer.releaseAllVideos(); }
说到这里还有一点可以说下,就是给视频弄圆角的时候,具体效果可以看上图,这里需要给TextureView设置圆角,一般的通过写shape设置background已经不适用了,好在网上找到一个方法:
public class TextureVideoViewOutlineProvider extends ViewOutlineProvider { private float mRadius; public TextureVideoViewOutlineProvider(float radius) { this.mRadius = radius; } @Override public void getOutline(View view, Outline outline) { Rect rect = new Rect(); view.getGlobalVisibleRect(rect); int leftMargin = 0; int topMargin = 0; Rect selfRect = new Rect(leftMargin, topMargin, rect.right - rect.left - leftMargin, rect.bottom - rect.top - topMargin); outline.setRoundRect(selfRect, mRadius); }}
最后给view设置就行:
mVideoView.setOutlineProvider(new TextureVideoViewOutlineProvider(radius));mVideoView.setClipToOutline(true);
好了,今天的分享就到这里了,也是百忙中抽空写完了,喜欢可以点播关注,不喜欢的可以提点意见 ~_~ 。
- Android Recyclerview列表自动播放视频
- Android在滚动列表中实现视频的播放(ListView & RecyclerView)
- (更新版)Android VideoPlayer 在滚动列表实现item视频播放(ListView控件和RecyclerView)
- Android在滚动列表中实现视频的播放(ListView & RecyclerView)
- Android列表嵌入视频播放
- html自动循环播放视频列表
- ListView & RecyclerView播放视频
- RecyclerView中播放视频
- Android 安卓RecyclerView显示本地视频并播放
- Android 列表播放视频和浮动播放窗口
- Android开机启动自动播放视频
- [iOS]列表视频播放
- android 列表中播放视频(仿搜狐视频、微视等视频播放)
- 在可滑动列表(ListView & RecyclerView)中实现视频播放
- 列表自动滚动播放
- 淘宝视频自动播放
- 视频自动循环播放
- Youtube 视频自动播放
- 欢迎使用CSDN-markdown编辑器
- SylixOS USB虚拟网卡框架
- EditText默认不弹出软件键盘
- 常用正则表达式汇总
- iOS-制作并调用Bundle资源包
- Android Recyclerview列表自动播放视频
- 去哪儿笔试:部分和问题 java
- Map
- 深度学习: 回归分析 评价方法
- 首页网站div制作(div+css概述,css选择器)
- ue4 改c++类名
- MySQL 操作语句大全
- [BZOJ]3036 绿豆蛙的归宿 期望dp
- setlocale函数---字符编码问题解决