仿网易视频列表连播炫酷效果 - v3.1 升级版-细节优化(网络状态切换、item点击事件等)

原创 2017-08-10 认真的 小苏

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

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

注重细节

细节优化:
  1. 点击上一个item 或 下一个item 平滑的滚动并播放。
  2. 网络状态切换的处理:从WiFi切换到数据、数据切换到WiFi、无网络时切换到WiFi 和 数据的处理。

1.item 点击事件处理

这个就不细讲,非常常见的知识点,主要讲下滑动时的处理。
看下面 Adapter 代码

private ItemClickListener itemClickListener;

public VideoAdapter(Context context, ItemClickListener itemClickListener) {
        this.context = context;
        this.itemClickListener = itemClickListener;
 }

@Override
public void onBindViewHolder(final VideoFeedHolder holder, final int position) {
        holder.update(position, mlist);
        View itemView = holder.itemView;
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                itemClickListener.onItemClick(v, position);
            }
        });
    }

注意要在holder 中处理 ,itemView 是否可以点击

/**
     * 显示当前播放的 item 的蒙层和 图片
     */
    public void visMasked() {
        img.setVisibility(View.VISIBLE);
        video_masked.setVisibility(View.VISIBLE);
        ll_not_wifi.setVisibility(View.GONE);
        itemView.setEnabled(true);
    }

    /**
     * 隐藏当前播放的 item 的蒙层和 图片
     */
    public void goneMasked() {
        img.setVisibility(View.GONE);
        video_masked.setVisibility(View.GONE);
        ll_not_wifi.setVisibility(View.GONE);
        itemView.setEnabled(false);
    }

Activity 中点击事件滑动的处理,看下面代码

  adapter = new VideoAdapter(this, new ItemClickListener() {
            @Override
            public void onItemClick(View v, Object object) {
                //手动点击下一个,暂停之前的 并显示蒙层
                stopPlayer(playerPosition);
                missVideoTips();
                // 缓慢平滑的滚动到下一个
                itemPosition = (int) object;
                playerPosition = itemPosition;
                rl_video.smoothScrollToPosition(itemPosition);
            }
        });

2.网络状态切换的处理

我们需要动态的监听网络状态,所以需要写一个BroadcastReceiver , 监听网络状态,并发送广播。

网络判断工具类

public class NetChangeManager {
    private static NetChangeManager netChangeManager;
    private Context context;

    public NetChangeManager() {
    }

    public static NetChangeManager getInstance() {
        if (netChangeManager == null) {
            synchronized (NetChangeManager.class) {
                if (netChangeManager == null) {
                    netChangeManager = new NetChangeManager();
                }
            }
        }
        return netChangeManager;
    }

    /**
     * 获取网络类型
     *
     * @return 返回值 -1:没有网络  1:WIFI网络 2:wap网络3:net网络
     */
    public int getNetType() {
        int netType = -1;
        ConnectivityManager connMgr = (ConnectivityManager) VideoApp.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo == null) {
            return netType;
        }
        int nType = networkInfo.getType();
        Log.e("networkInfo", "networkInfo.getExtraInfo() is " + networkInfo.getExtraInfo());
        if (nType == ConnectivityManager.TYPE_MOBILE) {
            if (networkInfo.getExtraInfo() == null) {
                netType = 2;
            } else {
                if (networkInfo.getExtraInfo().toLowerCase().equals("cmnet")) {
                    netType = 3;
                } else {
                    netType = 2;
                }
            }
        } else if (nType == ConnectivityManager.TYPE_WIFI) {
            netType = 1;
        }
        return netType;
    }

    /**
     * 当前是否有网络
     *
     * @return true - 有网  false 无网
     */
    public boolean hasNet() {
        return getNetType() != -1;
    }
}

下面我们看一下 ,网络监听的广播。

public class NetworkConnectChangedReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo activeNetworkInfo = manager.getActiveNetworkInfo();
        if (activeNetworkInfo != null) {
            if (activeNetworkInfo.isConnected()) {
                if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                    if (listener != null) {
                        Log.e("linksu",
                                "onReceive(NetworkConnectChangedReceiver.java:34) 切换到数据流量");
                        listener.dataNetwork(true);
                    }
                } else if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                    if (listener != null) {
                        Log.e("linksu",
                                "onReceive(NetworkConnectChangedReceiver.java:40) 切换到WiFi");
                        listener.wifiNetwork(true);
                    }
                }
            } else {
                if (listener != null) {
                    Log.e("linksu",
                            "onReceive(NetworkConnectChangedReceiver.java:47) 无网络连接");
                    listener.notNetWork();
                }
            }
        } else {
            if (listener != null) {
                Log.e("linksu",
                        "onReceive(NetworkConnectChangedReceiver.java:54) 无网络连接");
                listener.notNetWork();
            }
        }
    }

    private ConnectChangedListener listener;

    public void setConnectChangeListener(ConnectChangedListener listener) {
        this.listener = listener;
    }

    public interface ConnectChangedListener {
        void wifiNetwork(boolean flag);

        void dataNetwork(boolean flag);

        void notNetWork();

    }
}

holder 中处理网络变化情况,在开始播放一个视频时,先调用这个方法

/**
     * 判断是不是WiFi的情况
     */
    public void playerWifi() {
        if (!NetChangeManager.getInstance().hasNet()) {
            img.setVisibility(View.VISIBLE);
            ll_not_wifi.setVisibility(View.GONE);
            iv_video_feed_start.setEnabled(false);
        } else {
            if (Constants.VIDEO_FEED_WIFI) {
                ll_not_wifi.setVisibility(View.GONE);
                iv_video_feed_start.setEnabled(false);
            } else {
                int netType = NetChangeManager.getInstance().getNetType();
                if (netType != 1) {// 不是WiFi下的情况
                    img.setVisibility(View.GONE);
                    video_masked.setVisibility(View.GONE);
                    ll_not_wifi.setVisibility(View.VISIBLE);
                    iv_video_feed_start.setEnabled(true);
                } else {
                    ll_not_wifi.setVisibility(View.GONE);
                    iv_video_feed_start.setEnabled(false);
                }
            }
        }
    }

 /**
     * 停止滚动手指抬起时 动态添加播放器,开始播放视频,并获取之前的播放进度
     *
     * @param recyclerView
     */
    private void aoutPlayVideo(final RecyclerView recyclerView) {
        if (!lVideoView.isPlayer()) {
            VideoFeedHolder childViewHolder = (VideoFeedHolder) recyclerView.findViewHolderForAdapterPosition(itemPosition);
            if (childViewHolder != null) {
                // 注册监听以及隐藏蒙层
                childViewHolder.registerVideoPlayerListener(this);
                childViewHolder.goneMasked();
                childViewHolder.playerWifi();
                if (!NetChangeManager.getInstance().hasNet()) { // 无网络的情况
                    Toast.makeText(this, "无法连接到网络,请稍后再试", Toast.LENGTH_SHORT).show();
                } else {
                    int netType = NetChangeManager.getInstance().getNetType();
                    if (netType == 1 || Constants.VIDEO_FEED_WIFI) { // WiFi的情况下,或者允许不是WiFi情况下继续播放
                        // 动态添加播放器
                        View itemView = childViewHolder.itemView;
                        FrameLayout frameLayout = (FrameLayout) itemView.findViewById(R.id.ll_video);
                        frameLayout.removeAllViews();
                        ViewGroup last = (ViewGroup) lVideoView.getParent();//找到videoitemview的父类,然后remove
                        if (last != null && last.getChildCount() > 0) {
                            last.removeAllViews();
                        }
                        frameLayout.addView(lVideoView);
                        // 获取播放进度
                        TabFragMainBeanItemBean itemBean = itemBeens.get(itemPosition);
                        long videoProgress = itemBean.videoProgress;
                        long duration = itemBean.mDuration;
                        if (videoProgress != 0 && videoProgress != duration) { // 跳转到之前的进度,继续播放
                            lVideoView.startLive(itemBean.video_url);
                            lVideoView.setSeekTo(videoProgress);
                        } else {//从头播放
                            lVideoView.startLive(itemBean.video_url);
                        }
                    }
                }
            }
        }
    }

最后一步,在Activity中注册广播,监听网络状态变化,处理如下:

 @Override
    public void wifiNetwork(boolean flag) {
        aoutPlayVideo(rl_video);
    }

    @Override
    public void dataNetwork(boolean flag) {
        Log.e("linksu", "onReceive(dataNetwork:273) 切换到数据流量");
        if (!Constants.VIDEO_FEED_WIFI) {
            dataNetwork(itemPosition);
            aoutPlayVideo(rl_video);
        }
    }

    @Override
    public void notNetWork() {

    }

    /**
     * 数据流量时显示的逻辑
     *
     * @param position
     */
    private void dataNetwork(int position) {
        VideoFeedHolder childViewHolder = (VideoFeedHolder) rl_video.findViewHolderForAdapterPosition(position);
        if (childViewHolder != null) {
            View itemView = childViewHolder.itemView;
            FrameLayout frameLayout = (FrameLayout) itemView.findViewById(R.id.ll_video);
            frameLayout.removeAllViews();
            lVideoView.stopVideoPlay();
            TabFragMainBeanItemBean itemBean = itemBeens.get(position);
            itemBean.videoProgress = currentPosition;
            itemBean.mDuration = mDuration;
            itemBeens.set(position, itemBean);
        }
    }

细节方面,处理完毕,如发现其他细节问题,请尽情的提出问题吧。
最后的最后,请不要客气,尽情的砸issue或者pull request过来吧!(https://github.com/susussa/VideoFeed)

仿网易视频列表连播炫酷效果 - v3.1 升级版-细节优化(网络状态切换、item点击事件等)_第1张图片
专题封面

你可能感兴趣的:(仿网易视频列表连播炫酷效果 - v3.1 升级版-细节优化(网络状态切换、item点击事件等))