最近公司出了新的需求, 想让视频列表滑到哪里,哪里就自动播放.
于是乎,深海开始动手了:
第一步,先让视频可以手动点击播放
这个简单:就往ViewHolder里放一个视频播放器就可以了
着重说一下,因为播放器框架问题以及性能相关问题,播放完一个视频,播放下一个视频的时候要初始化播放器
让整个列表,始终只有一个播放器在播放视频.
重点代码: MediaPlayerManager.instance().releaseMediaPlayer(); 初始化播放器
/*
*作者:赵星海
*时间:2019/7/30 16:31
*用途: ViewHolder中,播放器点击事件
*/
mVideoView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mVideoView == null) return;
if (isPlay) {
isPlay = false;
MediaPlayerManager.instance().pause(); // 停止播放
mVideoView.setVisibility(View.GONE);
play.setVisibility(View.VISIBLE);
} else {
if (getPosition()!=Attention_Adapter.startPosition){
MediaPlayerManager.instance().releaseMediaPlayer();
}
isPlay = true;
MediaPlayerManager.instance().start();
mVideoView.setVisibility(View.VISIBLE);
play.setVisibility(View.GONE);
}
}
});
我知道看这个代码你会有几点疑惑,我依次解释一下其用途,
然后你也可采用类似方式实现,毕竟可能你我用的播放器不同,或者业务逻辑不同
isPlay: → boolean类型,这是一个是否正在播放的标记,因为要让播放器只运行一个,所以提成了全局
MediaPlayerManager; → 这是我用的播放器的控制器类,负责暂停,初始化等功能
play.setVisibility(View.GONE) → 一个盖在播放器上面的一个小浮标,无需深究
第二步,让视频自动播放
实现RecyclerView的滑动监听:
/*
*作者:赵星海
*时间:2019/7/30 15:35
*用途: RecyclerView滑动监听_确定自动播放的位置和回收点
*/
mRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
private int thisPosition = -1;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
switch (newState) {
case RecyclerView.SCROLL_STATE_IDLE: //滚动停止
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (layoutManager != null) {
int firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
int lastVisibleItem = layoutManager.findLastVisibleItemPosition();
int eddVisibleItem = layoutManager.findLastCompletelyVisibleItemPosition();
if (eddVisibleItem == thisPosition) return;
thisPosition = eddVisibleItem;
int thisVideoView = eddVisibleItem - firstVisibleItem;
if (layoutManager != null && layoutManager.getChildAt(thisVideoView) != null
&& layoutManager.getChildAt(thisVideoView).findViewById(R.id.attention_holder_video) != null) {
VideoView videoView = layoutManager.getChildAt(thisVideoView).findViewById(R.id.attention_holder_video);
videoView.start();
LogUtils.loge("开始播放新视频");
}
}
break;
case RecyclerView.SCROLL_STATE_DRAGGING: //手指拖动
break;
case RecyclerView.SCROLL_STATE_SETTLING: //惯性滚动
break;
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
这里要注意,在监听里的匿名内部类中定义了一个变量:
private int thisPosition = -1; //代表当前屏幕中完整显示的Item
初次尝试:通过获取屏幕中显示的第一个Item和最后一个Item来确定thisPosition:
两个核心方法:
int firstPosition = layoutManager.findFirstVisibleItemPosition();
int lastPosition = layoutManager.findLastVisibleItemPosition();
核心思想: (深海又要开始画图了...)
上图是当初深海取当前位置thisPosition的方案.
代码体现是这样的:
if (lastPosition-firstPosition ==1){
thisPosition = firstPosition;
}else if(lastPosition-firstPosition >1){
thisPosition = firstPosition+1;
}
最后的左边减去最开始的坐标,获取到屏幕中显示Item的数量,然后通过这个来确定thisPosition的取值方法:
但是最终这个方案被废弃了,在实际的使用中遇到很多问题,比如遇到两个条目过大的时候 第一个条目仅仅滑上去一点点,也会直接
播放下面只露头的Item.....
后来,我去翻了一下layoutManager的源码. 当!当!当!当~! 我发现了这个方法 findLastCompletelyVisibleItemPosition()
这个方法可以直接获取当前屏幕中完整显示的Item,返回最下面的Item.
因为 layoutManager.getChildAt(thisVideoView) 方法参数是该条目在当前页的相对坐标,而不是所有控件的坐标
所以,用当前的坐标findLastCompletelyVisibleItemPosition(),减去第一个Item的坐标firstVisibleItem,就得到了当前完整显示的Item的相对坐标.
然后就可以用相对坐标作为 layoutManager.getChildAt(thisVideoView)的参数获取到当前完整显示的最后一个item的VideoVIew控件去控制播放 , 完毕!
如果大家还有什么不懂的地方,或者有更好的建议,欢迎大家评论区留言! 看到必回! 谢谢!
标签:播放器,thisPosition,int,Item,自动播放,Android,RecyclerView,layoutManager From: https://blog.51cto.com/u_13520184/6152115