美文网首页Android UI特效实现
仿抖音视频播放列表

仿抖音视频播放列表

作者: 麻油里 | 来源:发表于2018-09-18 16:50 被阅读54次

    首先是效果图

    FakeDouYin.gif

    github源码

    实现方案

    全屏滚动列表

    实现方式 RecyclerView+PagerSnapHelper。方便起见,使用了开源库DingMouRen/LayoutManagerGroup中的ViewPagerLayoutManager。滑动到某一页时开始播放那一页的视频,同时停止播放之前播放的视频。

    播放器

    使用的是B站开源的ijkplayer。api与原生MediaPlayer类似。另外需要自己编译支持https。
    原本想使用七牛的免费播放器PLDroidPlayer,但是存在一些小问题,比如来回切换时,在部分设备上会有卡顿一下的情况等。

    边缓存边播放

    使用的是AndroidVideoCache。通过代理实现一边缓存视频流,一边播放。可以自己设置最大缓存空间等,调用也十分简单。


    遇到的问题

    IjkMediaPlayer空指针

    快速来回滑动时,有时IjkMediaPlayer会在native报空指针错误。我在播放的视频被滑出可视范围后处理是

    mMediaPlayer.stop();
    

    理论上我没有调用release,应该不会出现这个问题啊。
    后来就改成了直接释放,在使用时重新创建。改成这样后就没有再出现这个问题。

     /**
         * 停止播放时直接释放资源,在设置播放地址时再初始化
         */
        public void stopPlayback() {
            if (mMediaPlayer != null) {
                mMediaPlayer.stop();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
        }
    
       /**
         * 设置播放地址。同时创建一个新的player实例
         *
         * @param url
         */
        public void setVideoPath(String url) {
            try {
              createPlayer();
              mMediaPlayer.setDataSource(mProxyCacheServer.getProxyUrl(url));  
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        private void createPlayer() {
            mMediaPlayer = new IjkMediaPlayer();
            mMediaPlayer.setOnPreparedListener(this);
            if (mSurface != null) {
                mMediaPlayer.setSurface(mSurface);
            }
        }
    

    RecyclerView.SCROLL_STATE_IDLE不调用

    有一种情况,在监听RecyclerView的滑动回调里接收不到RecyclerView.SCROLL_STATE_IDLE这个状态的回调。
    具体的操作方法是从第二个视频滑动到第一个视频的时候,滑动到一半松手,在滑动到顶部之前再按下,往下拖拽。
    第一次碰到的时候也是很懵逼,这也行?
    解决方法是手动调用

    setScrollState(SCROLL_STATE_DRAGGING);
    

    完整解决代码

    recyclerView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent e) {
                    final int action = e.getActionMasked();
                    switch (action) {
                        case MotionEvent.ACTION_DOWN://手指按下
                            break;
                        case MotionEvent.ACTION_CANCEL:
                            break;
                        case MotionEvent.ACTION_MOVE://手指移动(从手指按下到抬起 move多次执行)
                            break;
                        case MotionEvent.ACTION_UP://手指抬起
                            if (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING &&
                                    pagerLayoutManager.findSnapPosition() == 0) {
                                if (recyclerView.getChildAt(0).getY() == 0 &&
                                        recyclerView.canScrollVertically(1)) {//下滑操作
                                    recyclerView.stopScroll();
                                }
                            }
                            break;
                        default:
                            break;
                    }
    
                    return false;
                }
            });
    

    如果喜欢的话就点个赞吧。欢迎start

    相关文章

      网友评论

      • Superman_94f4:你好,我想问下 怎么指定 recyclerview 播放的条目呢, 比如 我设置指定播放 第五条。playVideo(int position)这个方法里 viewHolder为空嘛
        麻油里:先调用recyclerView或者layoutManager的scrollToPosition方法就可以了。

      本文标题:仿抖音视频播放列表

      本文链接:https://www.haomeiwen.com/subject/tbjrnftx.html