仿网易视频列表连播炫酷效果 - v3.1 升级版-细节优化(网络状态切换、item点击事件等)
2018-02-03 09:27
701 查看
原创 2017-08-10 认真的 小苏
2、仿网易/QQ空间视频列表滚动连播炫酷效果(V2.0 填坑之路) 想看源码的,看这篇文章。
3、仿网易视频列表滚动连播炫酷效果(v3.0 稳定版-思想改变及优化) 稳定版-进行优化和思想上的改变。
4、RecyclerView 平滑滚动可控制滚动速度的终极解决方案
5、仿网易视频列表连播炫酷效果 - v3.1 升级版-细节优化(网络状态切换、item点击事件等)
持续更新中…..
![](http://img1.imgtn.bdimg.com/it/u=2987366732,723989291&fm=26&gp=0.jpg)
细节优化:
点击上一个item 或 下一个item 平滑的滚动并播放。
网络状态切换的处理:从WiFi切换到数据、数据切换到WiFi、无网络时切换到WiFi 和 数据的处理。
看下面 Adapter 代码
注意要在holder 中处理 ,itemView 是否可以点击
Activity 中点击事件滑动的处理,看下面代码
网络判断工具类
下面我们看一下 ,网络监听的广播。
holder 中处理网络变化情况,在开始播放一个视频时,先调用这个方法
最后一步,在Activity中注册广播,监听网络状态变化,处理如下:
细节方面,处理完毕,如发现其他细节问题,请尽情的提出问题吧。
最后的最后,请不要客气,尽情的砸issue或者pull request过来吧!(https://github.com/susussa/VideoFeed)
视频列表滚动连播技术探究系列
1、仿网易/QQ空间视频列表滚动连播炫酷效果(V1.0 挖坑之路)。2、仿网易/QQ空间视频列表滚动连播炫酷效果(V2.0 填坑之路) 想看源码的,看这篇文章。
3、仿网易视频列表滚动连播炫酷效果(v3.0 稳定版-思想改变及优化) 稳定版-进行优化和思想上的改变。
4、RecyclerView 平滑滚动可控制滚动速度的终极解决方案
5、仿网易视频列表连播炫酷效果 - v3.1 升级版-细节优化(网络状态切换、item点击事件等)
持续更新中…..
![](http://img1.imgtn.bdimg.com/it/u=2987366732,723989291&fm=26&gp=0.jpg)
细节优化:
点击上一个item 或 下一个item 平滑的滚动并播放。
网络状态切换的处理:从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.0 稳定版-终极优化)
- ListView中item点击事件、item保持选中状态以及其他细节
- 利用RecycleView实现类似ListView的Item点击,长按等操作事件以及点击后每一项在添加一个列表
- 关于RecyclerView列表点击事件ripple效果失效的问题
- 处理好item点击事件的gallery(画廊)效果(无bug)
- RecyclerView的Item点击事件,增加删除Item瀑布流动画效果,长按拖动Item,RecyclerView复杂布局、实现新闻频道选择器
- ListView 的item中有多个控件导致列表点击事件失效解决
- Android通过请求网络数据实现ListView,ListView的优化、图片的缓存、子控件的点击事件。
- android中listview的item点击切换实现效果(选择器selector)
- 【Android 界面效果48】Android-RecyclerView-Item点击事件设置
- ListView item点击事件问题:第一次点击有效,再次点击item无效。场景是在item的展开效果
- [Android界面] GridView 中含有两个以上的Button时Item点击事件没有效果
- [Android | Material Design] RecyclerView Item点击事件 添加水波纹效果 两种办法
- js模拟QQ面板拖拽效果及状态切换效果(DOM事件)
- radioButton 或者ImageButton存在item里的话 列表的点击事件就不可用
- Android实现单页显示3个Item的ViewPager炫酷切换效果
- jQuery实现点击单选按钮切换选中状态效果
- Android如何处理列表控件的item同时点击事件
- 仿网易/QQ空间视频列表滚动连播炫酷效果
- Android基础:listview的item点击事件会使里面的Button也出现按压的效果