安卓自定义控件手游直播开发Android知识

仿网易/QQ空间视频列表滚动连播炫酷效果(V1.0 挖坑之路)

2017-07-27  本文已影响618人  289346a467da

原创 2017-07-27 认真的 小苏

6401.jpg

视频列表滚动连播技术探究系列

1、仿网易/QQ空间视频列表滚动连播炫酷效果(V1.0 挖坑之路)
2、仿网易/QQ空间视频列表滚动连播炫酷效果(V2.0 填坑之路) 想看源码的,看这篇文章。
3、仿网易视频列表滚动连播炫酷效果(v3.0 稳定版-思想改变及优化) 稳定版-进行优化和思想上的改变。
4、RecyclerView 平滑滚动可控制滚动速度的终极解决方案
5、仿网易视频列表连播炫酷效果 - v3.1 升级版-细节优化(网络状态切换、item点击事件等)
持续更新中.....

技术前沿

万众瞩目Instant Apps终于全面问世啦 感兴趣的同学去看一下吧!

来个段子解解压

有个精神病到了银行,用手敲了敲柜台玻璃,问柜员:这是防弹玻璃吗?柜员:是的。精神病:能防得住炸弹吗?柜员吓得脸色苍白,说:不能!精神病从兜里掏出一对大小王贴在玻璃上说:“炸”!!!二十秒后,只见柜员怯怯的说出3个字。。。精神病满意的走了!

仿网易视频列表滚动连播炫酷效果

先看效果图,再说实现思想


gif不清晰,主要看实现的功能

实现思路

首先分析功能:1、滚动时不播放,但是要亮起,当前屏幕内,item view显示百分比最大的一个。
2、停止滚动且手指抬起时自动播放。
3、播放完当前的视频,自动滚动到下一个并自动播放。
4、正在播放的当前视频,快要播放完毕时,弹出TextView提示播放下一个,点击TextView自动滚动到下一个。
以上就是我们要实现的功能点。

分析功能点

  1. 滚动时不播放,但是要亮起,当前屏幕内,item view显示百分比最大的一个

分析: 看到滚动两个字,首要想起的是滚动监听(这里使用RecyclerView) addOnScrollListener,我们要在列表滚动时,计算屏幕内item 的数量,且找出item view 显示的百分比,进行比较,若其中一个item 百分比为:100 或百分比占最大,我们亮起这个item,其他的item是暗色的。

ok,顺着这个思路,往下走,如何获取一个view的百分比呢?
这是我从网上搜到的,这样我们就可以获取一个view他在当前屏幕内所占的百分比了。

 private final Rect mCurrentViewRect = new Rect();
 public int getVisibilityPercents(View view) {

        int percents = 100;

        view.getLocalVisibleRect(mCurrentViewRect);

        int height = view.getHeight();

        if (viewIsPartiallyHiddenTop()) {
            // view is partially hidden behind the top edge
            percents = (height - mCurrentViewRect.top) * 100 / height;
        } else if (viewIsPartiallyHiddenBottom(height)) {
            percents = mCurrentViewRect.bottom * 100 / height;
        }

        return percents;
    }

    private boolean viewIsPartiallyHiddenBottom(int height) {
        return mCurrentViewRect.bottom > 0 && mCurrentViewRect.bottom < height;
    }

    private boolean viewIsPartiallyHiddenTop() {
        return mCurrentViewRect.top > 0;
    }

既然拿到了百分比,就可以在recyclerview 的滚动监听中进行计算了,看下面代码

 rl_video.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_IDLE://停止滑动
                        mScrollState = false;
                        //滑动停止和松开手指时,调用此方法 进行播放
                        aoutPlayVideo(recyclerView);
                        break;
                    case RecyclerView.SCROLL_STATE_DRAGGING://用户用手指滚动
                        mScrollState = true;
                        break;
                    case RecyclerView.SCROLL_STATE_SETTLING://自动滚动
                        mScrollState = true;
                        break;
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                if (layoutManager instanceof LinearLayoutManager) {
                    LinearLayoutManager linearManager = (LinearLayoutManager) layoutManager;
                    //获取最后一个可见view的位置
                    lastItemPosition = linearManager.findLastVisibleItemPosition();
                    //获取第一个可见view的位置
                    firstItemPosition = linearManager.findFirstVisibleItemPosition();
                    //获取可见view的总数
                    visibleItemCount = linearManager.getChildCount();
                    if (mScrollState) { //滚动
                        srcollVisible(recyclerView, firstItemPosition, lastItemPosition, visibleItemCount);
                    } else { //停止 第一次进入时调用此方法,进行播放
                        aoutPlayVideo(recyclerView);
                    }
                }
            }
        });

很简单的逻辑,同理我们的功能2 也就能实现了

  1. 停止滚动且手指抬起时自动播放。
    什么时候回调这个状态呢 case RecyclerView.SCROLL_STATE_IDLE,可以打个log 测试下,当列表停止滑动且手指抬起时,就会调这个状态。那我们就可以在这个状态里,实现播放视频的逻辑了。

  2. 如何计算百分比,实现思路非常简单,简单的for循环而已,具体的都写有注释。

   /**
     * 滚动时 判断哪个view 显示百分比最大,哪个最大 视图亮起
     *
     * @param recyclerView
     * @param firstItemPosition
     * @param lastItemPosition
     * @param visibleItemCount  屏幕显示的item数量
     */
    private void srcollVisible(RecyclerView recyclerView, int firstItemPosition, int lastItemPosition, int visibleItemCount) {

        for (int i = 0; i < visibleItemCount; i++) {
            if (recyclerView != null) {
                View childAt = recyclerView.getChildAt(i).findViewById(R.id.visiabile);
                recyclerView.getChildAt(i).findViewById(R.id.video_masked).setVisibility(View.VISIBLE);
                int visibilityPercents = VisibilePercentsUtils.getInstance().getVisibilityPercents(childAt);
                if (visibilityPercents == 100) {
                    position = i;
                }
            }
        }

        itemPosition = (firstItemPosition + position);
        recyclerView.getChildAt(position).findViewById(R.id.video_masked).setVisibility(View.GONE);
        Log.e("linksu MainActivity",
                "srcollVisible(MainActivity.java:94) itemPosition --> " + itemPosition + " playerPosition:" + playerPosition);
        if (playerPosition == itemPosition) {// 说明还是之前的 item 并没有滑动到下一个
            Log.e("linksu MainActivity",
                    "srcollVisible(MainActivity.java:109) 还是当前的item 没有变化 继续播放");
        } else { // 说明亮起的已经不是当前的item了,是下一个或者之前的那个,我们停止变暗的item的播放
            Log.e("linksu MainActivity",
                    "srcollVisible(MainActivity.java:120) stopPlayer:" + playerPosition);
            VideoHolder childViewHolder = (VideoHolder) recyclerView.findViewHolderForAdapterPosition(playerPosition);
            if (childViewHolder != null) {
                childViewHolder.stopPlayer();
                childViewHolder.unRegisterVideoPlayerListener();// 注意我们需要解除上一个item的监听,不然会注册多个监听
            }
            playerPosition = itemPosition;
        }
    }
  1. 播放完当前的视频,自动滚动到下一个并自动播放。
    思路:监听视频播放状态(这里用的是七牛开源的播放器)。
public interface OnVideoPlayerListener {
    void onVideoPrepared();

    void onVideoCompletion();

    void onVideoError(int i,String error);

    void onBufferingUpdate();

    void onVideoStopped();

    void onVideoPlayingPro(long currentPosition, long mDuration, int mPlayStatus);
}

然后再ViewHolder 中实现监听,并在ViewHolder 中写一个接口 ,Activity 中实现这个接口


    public interface onHolderVideoPlayerListener {
        void videoError();

        void videoCompletion();

        void videoBuffer();

        void videoTips();

        void missVideoTips();
    }

    private onHolderVideoPlayerListener listener;

    /**
     * 注册监听
     *
     * @param listener
     */
    public void registerVideoPlayerListener(onHolderVideoPlayerListener listener) {
        this.listener = listener;
    }

    /**
     * 解除监听
     */
    public void unRegisterVideoPlayerListener() {
        if (listener != null) {
            listener = null;
        }
    }

需要注意的是我们要为 item 注册 和解除监听,否则item 移除屏幕后,还会继续监听,这样就乱套了。
同理,每个item的播放器也是及时的解除监听状态,否则我们拿到的播放进度会有问题。

ViewHolder 实现 OnVideoPlayerListener,

@Override
    public void onVideoPrepared() {

    }

    @Override
    public void onVideoCompletion() {
        if (listener != null) {
            img.setVisibility(View.VISIBLE);
            video_masked.setVisibility(View.VISIBLE);
            listener.videoCompletion();
            lVideoView.unOnVideoPlayerListener();// 注意 注销监听 否则之前的item 都会有监听
        }
    }

    @Override
    public void onVideoError(int i, String error) {
        if (listener != null) {
            listener.videoError();
        }
    }

    @Override
    public void onBufferingUpdate() {

    }

    @Override
    public void onVideoStopped() {
        img.setVisibility(View.VISIBLE);
        video_masked.setVisibility(View.VISIBLE);
        lVideoView.unOnVideoPlayerListener();// 注意 注销监听 否则之前的item 都会有监听
    }

    @Override
    public void onVideoPlayingPro(long currentPosition, long mDuration, int mPlayStatus) {
        float percent = (float) ((double) currentPosition / (double) mDuration);
        DecimalFormat fnum = new DecimalFormat("##0.0");
        float c_percent = 0;
        c_percent = Float.parseFloat(fnum.format(percent));
        if (0.8 <= c_percent) {
            if (listener != null) {
                listener.videoTips();
            }
        } else {
            if (listener != null) {
                listener.missVideoTips();
            }
        }
    }

Activity 的实现思路,看下面代码

implements VideoHolder.onHolderVideoPlayerListener

  @Override
    public void videoError() {

    }

    @Override
    public void videoCompletion() { //播放完成 播放下一个
        int p = (itemPosition + 1);
        rl_video.smoothScrollToPosition(p);
    }

    @Override
    public void videoBuffer() {

    }

    @Override
    public void videoTips() {
        mTv.setVisibility(View.VISIBLE);
    }

    @Override
    public void missVideoTips() {
        mTv.setVisibility(View.GONE);
    }


需要注意的是 当我们调用 rl_video.smoothScrollToPosition(p); recyclerview的滚动监听会回调,我们需要在这样滚动的时候这样处理

同理 ,下面这段代码也处理了,我们用手拖动时,若当前item 百分比最大 视频继续播放。

itemPosition = (firstItemPosition + position);
        recyclerView.getChildAt(position).findViewById(R.id.video_masked).setVisibility(View.GONE);
        Log.e("linksu MainActivity",
                "srcollVisible(MainActivity.java:94) itemPosition --> " + itemPosition + " playerPosition:" + playerPosition);
        if (playerPosition == itemPosition) {// 说明还是之前的 item 并没有滑动到下一个
            Log.e("linksu MainActivity",
                    "srcollVisible(MainActivity.java:109) 还是当前的item 没有变化 继续播放");
        } else { // 说明亮起的已经不是当前的item了,是下一个或者之前的那个,我们停止变暗的item的播放
            Log.e("linksu MainActivity",
                    "srcollVisible(MainActivity.java:120) stopPlayer:" + playerPosition);
            VideoHolder childViewHolder = (VideoHolder) recyclerView.findViewHolderForAdapterPosition(playerPosition);
            if (childViewHolder != null) {
                childViewHolder.stopPlayer();
                childViewHolder.unRegisterVideoPlayerListener();// 注意我们需要解除上一个item的监听,不然会注册多个监听
            }
            playerPosition = itemPosition;
        }
  1. 正在播放的当前视频,快要播放完毕时,弹出TextView提示播放下一个,点击TextView
    思路:这个就很简单了,上面的代码也有给出。我说一下思路,已知我们在ViewHolder 中监听视频播放状态同时也监听了播放进度,如下代码:
 @Override
    public void onVideoPlayingPro(long currentPosition, long mDuration, int mPlayStatus) {
        float percent = (float) ((double) currentPosition / (double) mDuration);
        DecimalFormat fnum = new DecimalFormat("##0.0");
        float c_percent = 0;
        c_percent = Float.parseFloat(fnum.format(percent));
        if (0.8 <= c_percent) {
            if (listener != null) {
                listener.videoTips();
            }
        } else {
            if (listener != null) {
                listener.missVideoTips();
            }
        }
    }

已知我们在Activity 中实现了监听 onHolderVideoPlayerListener ,这样就很好去处理了

   @Override
    public void videoTips() {
        mTv.setVisibility(View.VISIBLE);
    }

    @Override
    public void missVideoTips() {
        mTv.setVisibility(View.GONE);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv:
                int p = (itemPosition + 1);
                rl_video.smoothScrollToPosition(p);
                break;
        }
    }

这样我们就实现了所有的功能点,这里视频播放器我用的是七牛开源的播放器,具体的封装就不写出来了,都是写简单的监听以及回调。下面我给出主要的代码,供大家参考。
VideoHolder

package com.linksu.mydemo;

import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.linksu.video_manager_library.listener.OnVideoPlayerListener;
import com.linksu.video_manager_library.ui.LVideoView;

import java.text.DecimalFormat;
import java.util.List;

/**
 * ================================================
 * 作    者:linksus
 * 版    本:1.0
 * 创建日期:7/27 0027
 * 描    述:
 * 修订历史:
 * ================================================
 */
public class VideoHolder extends RecyclerView.ViewHolder implements OnVideoPlayerListener {
    View video_masked;
    TextView item_tv;
    List<String> mlist;
    ImageView img;
    LVideoView lVideoView;

    public VideoHolder(View itemView, List<String> mlist) {
        super(itemView);
        this.item_tv = (TextView) itemView.findViewById(R.id.item_tv);
        this.lVideoView = (LVideoView) itemView.findViewById(R.id.lvideoview);
        this.mlist = mlist;
        this.img = (ImageView) itemView.findViewById(R.id.img);
        this.video_masked = itemView.findViewById(R.id.video_masked);
    }

    public void update(int position) {
        String s = mlist.get(position);
        item_tv.setText(s);
    }

    public void player(int position) {
        String url = mlist.get(position);
        if (lVideoView != null) {
            lVideoView.setOnVideoPlayerListener(this);
            lVideoView.startLive(url);
        }
    }

    public void stopPlayer() {
        if (lVideoView != null) {
            lVideoView.stopVideoPlay();
        }
    }

    public void goneMasked() {
        img.setVisibility(View.GONE);
        video_masked.setVisibility(View.GONE);
    }

    @Override
    public void onVideoPrepared() {

    }

    @Override
    public void onVideoCompletion() {
        if (listener != null) {
            img.setVisibility(View.VISIBLE);
            video_masked.setVisibility(View.VISIBLE);
            listener.videoCompletion();
            lVideoView.unOnVideoPlayerListener();// 注意 注销监听 否则之前的item 都会有监听
        }
    }

    @Override
    public void onVideoError(int i, String error) {
        if (listener != null) {
            listener.videoError();
        }
    }

    @Override
    public void onBufferingUpdate() {

    }

    @Override
    public void onVideoStopped() {
        img.setVisibility(View.VISIBLE);
        video_masked.setVisibility(View.VISIBLE);
        lVideoView.unOnVideoPlayerListener();// 注意 注销监听 否则之前的item 都会有监听
    }

    @Override
    public void onVideoPlayingPro(long currentPosition, long mDuration, int mPlayStatus) {
        float percent = (float) ((double) currentPosition / (double) mDuration);
        DecimalFormat fnum = new DecimalFormat("##0.0");
        float c_percent = 0;
        c_percent = Float.parseFloat(fnum.format(percent));
        if (0.8 <= c_percent) {
            if (listener != null) {
                listener.videoTips();
            }
        } else {
            if (listener != null) {
                listener.missVideoTips();
            }
        }
    }

    public interface onHolderVideoPlayerListener {
        void videoError();

        void videoCompletion();

        void videoBuffer();

        void videoTips();

        void missVideoTips();
    }

    private onHolderVideoPlayerListener listener;

    /**
     * 注册监听
     *
     * @param listener
     */
    public void registerVideoPlayerListener(onHolderVideoPlayerListener listener) {
        this.listener = listener;
    }

    /**
     * 解除监听
     */
    public void unRegisterVideoPlayerListener() {
        if (listener != null) {
            listener = null;
        }
    }
}

VideoAdapter

package com.linksu.mydemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

/**
 * ================================================
 * 作    者:linksus
 * 版    本:1.0
 * 创建日期:7/27 0027
 * 描    述:
 * 修订历史:
 * ================================================
 */
public class VideoAdapter extends RecyclerView.Adapter<VideoHolder> {
    private List<String> mlist;
    private Context context;

    public VideoAdapter(List<String> mlist, Context context) {
        this.mlist = mlist;
        this.context = context;
    }

    @Override
    public VideoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View inflater = LayoutInflater.from(context).inflate(R.layout.item, parent, false);
        return new VideoHolder(inflater, mlist);
    }

    @Override
    public void onBindViewHolder(VideoHolder holder, int position) {
        holder.update(position);
    }

    @Override
    public int getItemCount() {
        return mlist.size();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
}

MainActivity

package com.linksu.mydemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements VideoHolder.onHolderVideoPlayerListener, View.OnClickListener {

    private RecyclerView rl_video;
    private LinearLayoutManager layoutManager;
    private VideoAdapter adapter;
    private List<String> mList = new ArrayList<>();
    private boolean mScrollState = false;//是否处于滚动状态
    private int lastItemPosition;
    private int firstItemPosition;
    private int visibleItemCount;
    private TextView mTv;

    private int maxPercents = 0; // 最大显示百分比
    private int position = 0; // 最大显示百分比的屏幕内的子view的位置
    private int itemPosition = 0;// item 的位置
    private int playerPosition = 0;//正在播放item 的位置

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        for (int i = 0; i < 30; i++) {
            mList.add("http://rmrbtest-image.peopleapp.com/upload/video/201707/149999980163e892f63bf5cb85.mp4");
            mList.add("http://rmrbtest-image.peopleapp.com/upload/video/201707/1499914158feea8c512f348b4a.mp4");
            mList.add("http://rmrbtest-image.peopleapp.com/upload/video/201707/14991545431a9b3f9b6dd22db2.mp4");
            mList.add("http://rmrbtest-image.peopleapp.com/upload/video/201707/14991537461a9b3f9b6dd22db2.mp4");
            mList.add("http://rmrbtest-image.peopleapp.com/upload/video/201706/14963009301c0fd671d0e3ae1b.mp4");
            mList.add("http://rmrbtest-image.peopleapp.com/upload/video/201705/14962013161a9b3f9b6dd22db2.mp4");
            mList.add("http://rmrbtest-image.peopleapp.com/upload/video/201705/14958540601a9b3f9b6dd22db2.mp4");
            mList.add("http://rmrbtest-image.peopleapp.com/upload/video/201705/14957861291a9b3f9b6dd22db2.mp4");
        }
        rl_video = (RecyclerView) findViewById(R.id.rl_video);
        mTv = (TextView) findViewById(R.id.tv);
        mTv.setOnClickListener(this);
        layoutManager = new LinearLayoutManager(this);
        rl_video.setLayoutManager(layoutManager);
        adapter = new VideoAdapter(mList, this);
        rl_video.setAdapter(adapter);
        rl_video.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_IDLE://停止滑动
                        mScrollState = false;
                        //滑动停止和松开手指时,调用此方法 进行播放
                        aoutPlayVideo(recyclerView);
                        break;
                    case RecyclerView.SCROLL_STATE_DRAGGING://用户用手指滚动
                        mScrollState = true;
                        break;
                    case RecyclerView.SCROLL_STATE_SETTLING://自动滚动
                        mScrollState = true;
                        break;
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                if (layoutManager instanceof LinearLayoutManager) {
                    LinearLayoutManager linearManager = (LinearLayoutManager) layoutManager;
                    //获取最后一个可见view的位置
                    lastItemPosition = linearManager.findLastVisibleItemPosition();
                    //获取第一个可见view的位置
                    firstItemPosition = linearManager.findFirstVisibleItemPosition();
                    //获取可见view的总数
                    visibleItemCount = linearManager.getChildCount();
                    if (mScrollState) { //滚动
                        srcollVisible(recyclerView, firstItemPosition, lastItemPosition, visibleItemCount);
                    } else { //停止 第一次进入时调用此方法,进行播放
                        aoutPlayVideo(recyclerView);
                    }
                }
            }
        });
    }

    /**
     * 滚动时 判断哪个view 显示百分比最大,哪个最大 视图亮起
     *
     * @param recyclerView
     * @param firstItemPosition
     * @param lastItemPosition
     * @param visibleItemCount  屏幕显示的item数量
     */
    private void srcollVisible(RecyclerView recyclerView, int firstItemPosition, int lastItemPosition, int visibleItemCount) {

        for (int i = 0; i < visibleItemCount; i++) {
            if (recyclerView != null) {
                View childAt = recyclerView.getChildAt(i).findViewById(R.id.visiabile);
                recyclerView.getChildAt(i).findViewById(R.id.video_masked).setVisibility(View.VISIBLE);
                int visibilityPercents = VisibilePercentsUtils.getInstance().getVisibilityPercents(childAt);
                if (visibilityPercents == 100) {
                    position = i;
                }
            }
        }

        itemPosition = (firstItemPosition + position);
        recyclerView.getChildAt(position).findViewById(R.id.video_masked).setVisibility(View.GONE);
        Log.e("linksu MainActivity",
                "srcollVisible(MainActivity.java:94) itemPosition --> " + itemPosition + " playerPosition:" + playerPosition);
        if (playerPosition == itemPosition) {// 说明还是之前的 item 并没有滑动到下一个
            Log.e("linksu MainActivity",
                    "srcollVisible(MainActivity.java:109) 还是当前的item 没有变化 继续播放");
        } else { // 说明亮起的已经不是当前的item了,是下一个或者之前的那个,我们停止变暗的item的播放
            Log.e("linksu MainActivity",
                    "srcollVisible(MainActivity.java:120) stopPlayer:" + playerPosition);
            VideoHolder childViewHolder = (VideoHolder) recyclerView.findViewHolderForAdapterPosition(playerPosition);
            if (childViewHolder != null) {
                childViewHolder.stopPlayer();
                childViewHolder.unRegisterVideoPlayerListener();// 注意我们需要解除上一个item的监听,不然会注册多个监听
            }
            playerPosition = itemPosition;
        }
    }

    /**
     * 1.停止滚动手指抬起时 开始播放视频
     *
     * @param recyclerView
     */
    private void aoutPlayVideo(final RecyclerView recyclerView) {
        Log.e("linksu MainActivity",
                "aoutPlayVideo(MainActivity.java:112) position --> " + position);
        VideoHolder childViewHolder = (VideoHolder) recyclerView.findViewHolderForAdapterPosition(itemPosition);
        if (childViewHolder != null) {
            childViewHolder.registerVideoPlayerListener(this);
            childViewHolder.goneMasked();
            childViewHolder.player(itemPosition);
        }
    }

    @Override
    public void videoError() {

    }

    @Override
    public void videoCompletion() { //播放完成 播放下一个
        int p = (itemPosition + 1);
        rl_video.smoothScrollToPosition(p);
    }

    @Override
    public void videoBuffer() {

    }

    @Override
    public void videoTips() {
        mTv.setVisibility(View.VISIBLE);
    }

    @Override
    public void missVideoTips() {
        mTv.setVisibility(View.GONE);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv:
                int p = (itemPosition + 1);
                rl_video.smoothScrollToPosition(p);
                break;
        }
    }
}

以上就是主要实现的代码以及思路,纯手工,从思考到实现,不管实现什么功能思路最重要了,只要有了思路就可以用代码写出来,有不理解的地方可以留言给我。

推荐 好用的翻墙工具 ,主要是稳定。
仿网易/QQ空间视频列表滚动连播炫酷效果(V2.0 填坑之路) 想看源码的,看这篇文章。

专题封面
上一篇 下一篇

猜你喜欢

热点阅读