RecyclerView实现仿微博视频自动播放

近期遇到一个需求是做类似微博中视频在WiFi状态下自动播放,故写了一个简单的demo。重点代码都会贴出来,一些细节,项目中加了demo上并没有添加(例如:判断是否为WiFi状态)在这里说明一下。

需求:

1. 当视频item中视频部分露出超过1/3时,视频开始自动播放,当视频部分露出不足1/3时,视频停止播放,当下次满足自动播放要求时,从头播放。

2.当一屏中有2个满足以上自动播放规则的视频item时,一直轮播符合要求的第一个视频卡片

3.当下滑将已暂停的视频item视频部分超过1/3划回当前屏幕时,则该视频开始从头自动播放,之前正在播放的暂停播放且回到初始item样式

实现思路:

思路一:实例化一个视频播放器备用,实现滑动监听,判断符合播放标准item,将已经实例化的播放器动态add到该item指定展示位置进行播放,当该item不满足播放要求将其remove出去并将播放器置于初始状态待下次使用,然后继续判断符合要求item进行add...

思路二:将播放器置于item的布局中将其隐藏,实现滑动监听,判断符合播放位置,将其set给adapter并刷新,在onBindViewHolder方法中判断position是否等于播放位置,如果等于显示播放器并播放,不等于判断是否处于播放状态将其停止播放并释放资源以及隐藏。

思路一相对更加简单灵活并且性能好,然鹅...我是按照思路二做的。下面附上代码,其中有部分注释。

public class VideoListActivity extends BaseActivity {

    @InjectView(R.id.lv_video)
    RecyclerView lvVideo;
    private List<String> data;
    private MyAdapter adapter;
    private LinearLayoutManager mLayoutManager;
    int playPosition = 0;

    @Override
    public void onClick(View v) {

    }

    @Override
    public void bindLayout() {
        setContentView(R.layout.activity_video_list);
        ButterKnife.inject(this);
    }

    @Override
    public void initView() {
        data = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            data.add("http://crk.momocdn.com/mv/DD/E6/DDE62798-C8F1-4526-ACC1-E2240328B12E20180406_h264.mp4");
        }
        mLayoutManager = new LinearLayoutManager(this);
        //2 为RecyclerView创建布局管理器,这里使用的是LinearLayoutManager,表示里面的Item排列是线性排列
        lvVideo.setLayoutManager(mLayoutManager);

        adapter = new MyAdapter();
        lvVideo.setAdapter(adapter);
    }

    @Override
    public void setListener() {

    }

    @Override
    public void doBusiness() {

        lvVideo.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                recyclerView.getBaseline();
                //direction为 -1 表示手指向下滑动(屏幕向上滑动), 1 表示手指向上滑动(屏幕向下滑动)。
                if (mLayoutManager != null) {
                    int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();//得到显示屏内的第一个list的位置数position
                    View firstView = mLayoutManager.findViewByPosition(firstVisibleItem);
                    if (null != firstView) {
                        if (dy > 0) {


                            if (firstView.getHeight() + firstView.getTop() <= firstView.getHeight() / 3) {
                                //video stop or play second
                                if (mLayoutManager.getChildCount() < 2) {
                                    return;
                                }
                                if (playPosition == firstVisibleItem + 1) {
                                    return;
                                }
                                playPosition = firstVisibleItem + 1;
                                adapter.setPlay(playPosition);
                            } else {
                                if (playPosition == firstVisibleItem) {
                                    return;
                                }
                                playPosition = firstVisibleItem;
                                adapter.setPlay(playPosition);
                            }

                        }
                        if (dy < 0) {
                                if (firstView.getHeight() + firstView.getTop() >= firstView.getHeight() * 2 / 3) {
                                    //video stop or play second
                                    if (mLayoutManager.getChildCount() < 2) {
                                        return;
                                    }
                                    if (playPosition == firstVisibleItem) {
                                        return;
                                    }
                                    playPosition = firstVisibleItem;
                                    adapter.setPlay(playPosition);
                                } else {
                                    if (playPosition == firstVisibleItem + 1) {
                                        return;
                                    }
                                    playPosition = firstVisibleItem + 1;
                                    adapter.setPlay(playPosition);
                                }
                        }
                    }
                }
            }
        });

    }

    class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
        private int play = 0;

        public void setPlay(int play) {
            this.play = play;
            notifyDataSetChanged();
        }


        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            //加载布局文件
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_videolist, parent, false);
            ViewHolder vh = new ViewHolder(v);
            return vh;
        }

        @Override
        public void onBindViewHolder(final ViewHolder viewHolder, int position) {
            //将数据填充到具体的view中
            viewHolder.iv.setVisibility(View.VISIBLE);
            viewHolder.ijkPlayer.release();
            if (play == position) {
                viewHolder.ijkPlayer.setVisibility(View.VISIBLE);
                viewHolder.ijkPlayer.setVideoPath(data.get(position));
                viewHolder.iv.setVisibility(View.GONE);
                LogManager.e("======" + position);
            } else {
                viewHolder.iv.setVisibility(View.VISIBLE);
                viewHolder.ijkPlayer.setVisibility(View.GONE);
                viewHolder.ijkPlayer.release();
            }

            viewHolder.tv.setText("video" + position);
        }

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

        class ViewHolder extends RecyclerView.ViewHolder {
            TextView tv;
            ImageView iv;
            VideoPlayerIJK ijkPlayer;

            public ViewHolder(View itemView) {
                super(itemView);
                ijkPlayer = (VideoPlayerIJK) itemView.findViewById(R.id.sf_videoview);
                tv = (TextView) itemView.findViewById(R.id.tv);
                iv = (ImageView) itemView.findViewById(R.id.iv);
            }
        }
    }

}

总结:

遇到了一个很鸡肋的问题,自动播放了前几个后面的就不播放了问题就出在如下代码

1.View firstView = mLayoutManager.getChildAt(firstVisibleItem);
2.View firstView = mLayoutManager.findViewByPosition(firstVisibleItem);

1是开始出问题的代码,打了日志才发现,由于RecyclerView的复用机制而1方法只能获得复用的item因此无法获得准确的高度与位置后面被复用的就无法满足播放标准了。

经过网上各种查找最后在源码中找到了2这个讨人喜爱的方法最终问题解决。

在项目中使用思路没错可惜项目本身有坑,今天解决一天终于over了,蟹蟹自己。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
github地址: https://github.com/LoveZYForever/HXWeiboPhotoPicker 一. 安装 手动导入:将项目中的“HXWeiboPhotoPicker”文件夹拖入项目中 只使用照片选择功能 导入头文件 "HXPhotoViewController.h" 选完照片/视频后自动布局功能 导入头文件 "HXPhotoView.h" 二. 例子 Demo1 // 懒加载 照片管理类 - (HXPhotoManager *)manager { if (!_manager) { _manager = [[HXPhotoManager alloc] initWithType:HXPhotoManagerSelectedTypePhotoAndVideo]; } return _manager; } // 照片选择控制器 HXPhotoViewController *vc = [[HXPhotoViewController alloc] init]; vc.delegate = self; vc.manager = self.manager; [self presentViewController:[[UINavigationController alloc] initWithRootViewController:vc] animated:YES completion:nil]; // 通过 HXPhotoViewControllerDelegate 代理返回选择的图片以及视频 - (void)photoViewControllerDidNext:(NSArray *)allList Photos:(NSArray *)photos Videos:(NSArray *)videos Original:(BOOL)original // 点击取消 - (void)photoViewControllerDidCancel Demo2 // 懒加载 照片管理类 - (HXPhotoManager *)manager { if (!_manager) { _manager = [[HXPhotoManager alloc] initWithType:HXPhotoManagerSelectedTypePhotoAndVideo]; } return _manager; } self.navigationController.navigationBar.translucent = NO; self.automaticallyAdjustsScrollViewInsets = YES; HXPhotoView *photoView = [[HXPhotoView alloc] initWithFrame:CGRectMake((414 - 375) / 2, 100, 375, 400) WithManager:self.manager]; photoView.delegate = self; photoView.backgroundColor = [UIColor whiteColor]; [self.view addSubview:photoView]; // 通过 HXPhotoViewDelegate 代理返回 选择、移动顺序、删除之后的图片以及视频 - (void)photoViewChangeComplete:(NSArray *)allList Photos:(NSArray *)photos Videos:(NSArray *)videos Original:(BOOL)isOriginal // 当 HXPhotoView 更新frame改变大小时 - (void)photoViewUpdateFrame:(CGRect)frame WithView:(UIView *)view 三. 更多 具体代码看请下载项目 发现的哪里有不好或不对的地方麻烦请联系我,大家一起讨论一起学习进步... QQ : 294005139

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值