博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Android 进阶】仿抖音系列之列表播放视频(二)
阅读量:7040 次
发布时间:2019-06-28

本文共 6971 字,大约阅读时间需要 23 分钟。

上一篇中,我们实现了仿抖音上下翻页切换视频的效果,详见,这一篇,我们来实现抖音列表播放视频。

之前也在github上找到一个demo,,原理和我的一样,只是用起来比较麻烦。。。

先说下原理,这里用到了RecyclerView的onScrolled和onScrollStateChanged 监听,在onScrolled中判断当前可见的position,结合onScrollStateChanged中返回的当前RecyclerView的滑动状态,当是拖动和停止滚动时,可以播放;当是惯性滑动时,暂停播放。

关于RecyclerView3种滑动状态,RecyclerView.SCROLL_STATE_IDLE,RecyclerView.SCROLL_STATE_DRAGGING,RecyclerView.SCROLL_STATE_SETTLING,大家可以自行百度,这里不做过多的描述了。

rvList.addOnScrollListener(new RecyclerView.OnScrollListener() {            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();                firstVisibleItem = layoutManager.findFirstVisibleItemPosition();                lastVisibleItem = layoutManager.findLastVisibleItemPosition();            }            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                switch (newState) {                    case RecyclerView.SCROLL_STATE_IDLE://停止滚动                        /**在这里执行,视频的自动播放与停止*/                        autoPlayVideo(recyclerView);                        break;                    case RecyclerView.SCROLL_STATE_DRAGGING://拖动                        autoPlayVideo(recyclerView);                        break;                    case RecyclerView.SCROLL_STATE_SETTLING://惯性滑动                        JZVideoPlayer.releaseAllVideos();                        break;                }            }        });

布局就是一个RecyclerView,就不贴了,下面是Adapter

urlList = new ArrayList<>();        urlList.add("http://image.38.hn/public/attachment/201805/100651/201805181532123423.mp4");        urlList.add("http://image.38.hn/public/attachment/201803/100651/201803151735198462.mp4");        urlList.add("http://image.38.hn/public/attachment/201803/100651/201803150923220770.mp4");        urlList.add("http://image.38.hn/public/attachment/201803/100651/201803150922255785.mp4");        urlList.add("http://image.38.hn/public/attachment/201803/100651/201803150920130302.mp4");        urlList.add("http://image.38.hn/public/attachment/201803/100651/201803141625005241.mp4");        urlList.add("http://image.38.hn/public/attachment/201803/100651/201803141624378522.mp4");        urlList.add("http://image.38.hn/public/attachment/201803/100651/201803131546119319.mp4");        videoAdapter = new ListVideoAdapter(urlList);        rvList.setLayoutManager(new LinearLayoutManager(ListActivity.this));        rvList.setAdapter(videoAdapter);

Adapter这里自己做了个封装,可以用原生或者其他封装比较好的,这里就不贴了

class ListVideoAdapter extends BaseRecAdapter
{ public ListVideoAdapter(List
list) { super(list); } @Override public void onHolder(VideoViewHolder holder, String bean, int position) { holder.mp_video.setUp(bean, JZVideoPlayerStandard.CURRENT_STATE_NORMAL); if (position == 0) { holder.mp_video.startVideo(); } Glide.with(context).load(bean).into(holder.mp_video.thumbImageView); holder.tv_title.setText("第" + position + "个视频"); } @Override public VideoViewHolder onCreateHolder() { return new VideoViewHolder(getViewByRes(R.layout.item_video)); } } public class VideoViewHolder extends BaseRecViewHolder { public View rootView; public MyVideoPlayer mp_video; public TextView tv_title; public VideoViewHolder(View rootView) { super(rootView); this.rootView = rootView; this.mp_video = rootView.findViewById(R.id.mp_video); this.tv_title = rootView.findViewById(R.id.tv_title); } }

布局如下

这里使用的是 ,其中MyVideoPlayer 是之前公司项目需要,对其做的个性化定制,这里下面再说。

下来就是本篇的核心,通过判断可见项,暂停/播放视频,代码如下

/**     * 自动播放     */    private void autoPlayVideo(RecyclerView recyclerView) {        if (firstVisibleItem == 0 && lastVisibleItem == 0 && recyclerView.getChildAt(0) != null) {            MyVideoPlayer videoView = null;            if (recyclerView != null && recyclerView.getChildAt(0) != null) {                videoView = recyclerView.getChildAt(0).findViewById(R.id.mp_video);            }            if (videoView != null) {                if (videoView.currentState == JZVideoPlayer.CURRENT_STATE_NORMAL || videoView.currentState == JZVideoPlayer.CURRENT_STATE_PAUSE) {                    videoView.startVideo();                }            }        }        for (int i = 0; i <= lastVisibleItem; i++) {            if (recyclerView == null || recyclerView.getChildAt(i) == null) {                return;            }            MyVideoPlayer                    videoView = recyclerView.getChildAt(i).findViewById(R.id.mp_video);            if (videoView != null) {                Rect rect = new Rect();                //获取视图本身的可见坐标,把值传入到rect对象中                videoView.getLocalVisibleRect(rect);                //获取视频的高度                int videoHeight = videoView.getHeight();                if (rect.top <= 100 && rect.bottom >= videoHeight) {                    if (videoView.currentState == JZVideoPlayer.CURRENT_STATE_NORMAL || videoView.currentState == JZVideoPlayer.CURRENT_STATE_PAUSE) {                        videoView.startVideo();                    }                    return;                }                JZVideoPlayer.releaseAllVideos();            } else {                JZVideoPlayer.releaseAllVideos();            }        }    }

顺便说一下,为啥用JiaoZiVideoPlayer,就是因为 JZVideoPlayer.releaseAllVideos();,一句代码就可以暂停所有的播放器,否则自己要实现这个还是比较麻烦的

到这里,大概功能已经实现了,下面说说定制化的功能。需要去掉原播放器的进度条、按钮,点击视频,全屏播放,再次点击取消全屏。

我的做法是添加一个透明度为0的布局,覆盖在播放器上,这样实际上点击的是我们添加的布局

这里有个小技巧,可以粘贴源码中的布局,重要的事情说三遍,不要修改文件名、不要修改文件名、不要修改文件名,找到相关布局,设置android:visibility="gone",这样我们的项目中的布局就会替换掉原来的布局。

完整代码如下

jz_layout_standard.xml

还需要实现循环播放,这个比较简单,重写onAutoCompletion方法,当其播放完成时,继续播放即可。

@Override    public void onAutoCompletion() {        thumbImageView.setVisibility(View.GONE);        if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {            onStateAutoComplete();            setUp((String) getCurrentUrl(), JZVideoPlayer.SCREEN_WINDOW_FULLSCREEN);        } else {            super.onAutoCompletion();            setUp((String) getCurrentUrl(), JZVideoPlayer.CURRENT_STATE_NORMAL);        }        //循环播放        startVideo();    }

到这里,列表播放这个功能已经完成了。

最后,献上完整代码。

转载地址:http://twaal.baihongyu.com/

你可能感兴趣的文章
Android适配文件dimen自动生成代码
查看>>
走马观花--快餐学python笔记
查看>>
jquery轻量级富文本编辑器Trumbowyg
查看>>
(二十八)static关键字
查看>>
转 MySQL数据库基础
查看>>
ubuntu 解压命令全部
查看>>
Chrome教程(一)NetWork面板分析网络请求
查看>>
第十八回  基础才是重中之重~开发人员应学会用throw
查看>>
yarn简介
查看>>
基于H5实现的react拖拽排序组件
查看>>
【Flutter 学习笔记二】Dart 的基础概念和数据类型
查看>>
zepto源码ajax模块学习
查看>>
Vue v-for渲染页面,获取不到DOM元素解析
查看>>
一个典型案例为你解读TDSQL 全时态数据库系统
查看>>
视频云资深技术专家李彬:传统企业如何进行多媒体数字化转型?
查看>>
1. Two Sum (Easy)
查看>>
【linux】与 用户、权限 有关的常用命令
查看>>
对Javascript 类、原型链、继承的理解
查看>>
Go 的 fake-useragent 了解一下
查看>>
创建topic——kafka源码探究之一
查看>>