Android使用RecyclerView实现抖音主界面


参考:

https://developer.android.google.cn/reference/kotlin/androidx/recyclerview/widget/RecyclerView.OnChildAttachStateChangeListener.html

实现的效果如下:

在这里插入图片描述

实现视频的播放和停止播放


    /**
     * 停止播放
     */
    private void releaseVideo(View itemView) {
        final VideoView videoView = itemView.findViewById(R.id.video_view);
        final ImageView imgThumb = itemView.findViewById(R.id.img_thumb);
        final ImageView imgPlay = itemView.findViewById(R.id.img_play);
        videoView.stopPlayback();
        imgThumb.animate().alpha(1).start();
        imgPlay.animate().alpha(0f).start();
    }


    /**
     * 开始播放
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    private void playVideo(View itemView) {
        final VideoView videoView = itemView.findViewById(R.id.video_view);
        final ImageView imgPlay = itemView.findViewById(R.id.img_play);
        final ImageView imgThumb = itemView.findViewById(R.id.img_thumb);
        final RelativeLayout rootView = itemView.findViewById(R.id.root_view);
        final MediaPlayer[] mediaPlayer = new MediaPlayer[1];
        videoView.start();
        videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
            @Override
            public boolean onInfo(MediaPlayer mp, int what, int extra) {
                mediaPlayer[0] = mp;
                mp.setLooping(true);
                imgThumb.animate().alpha(0).setDuration(200).start();
                return false;
            }
        });
        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {

            }
        });


        imgPlay.setOnClickListener(new View.OnClickListener() {
            boolean isPlaying = true;

            @Override
            public void onClick(View v) {
                if (videoView.isPlaying()) {
                    imgPlay.animate().alpha(1f).start();
                    videoView.pause();
                    isPlaying = false;
                } else {
                    imgPlay.animate().alpha(0f).start();
                    videoView.start();
                    isPlaying = true;
                }
            }
        });
    }

监听每个Item的移出和移进

自定义LinearLayoutManager,并实现RecyclerView.OnChildAttachStateChangeListener接口。

OnChildAttachStateChangeListener接口源码如下:

    public interface OnChildAttachStateChangeListener {

        /**
         * Called when a view is attached to the RecyclerView.
         *
         * @param view The View which is attached to the RecyclerView
         */
        void onChildViewAttachedToWindow(@NonNull View view);

        /**
         * Called when a view is detached from RecyclerView.
         *
         * @param view The View which is being detached from the RecyclerView
         */
        void onChildViewDetachedFromWindow(@NonNull View view);
    }
  • onChildViewAttachedToWindow方法是将Item添加进来的时候调用;
  • onChildViewDetachedFromWindow方法是将Item移除出去的时候调用。

需要在onAttachedToWindow方法中调用addOnChildAttachStateChangeListener方法。

scrollVerticallyBy方法中实时获取垂直滑动的距离值;

自定义的MyLayoutManager代码如下:

public class MyLayoutManager extends LinearLayoutManager implements RecyclerView.OnChildAttachStateChangeListener {

    //根据这个参数来判断当前是上滑  还是下滑
    private int mDrift;
    //传进来的监听接口类
    private OnViewPagerListener onViewPagerListener;

    public MyLayoutManager(Context context) {
        super(context);
    }

    public MyLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    /**
     * 当MyLayoutManager完全放入到RecyclerView中的时候会被调用
     */
    @Override
    public void onAttachedToWindow(RecyclerView view) {
        view.addOnChildAttachStateChangeListener(this);
        super.onAttachedToWindow(view);
    }

    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        mDrift = dy;
        return super.scrollVerticallyBy(dy, recycler, state);
    }

    @Override
    public boolean canScrollVertically() {
        return true;
    }

    /**
     * 将Item添加进来的时候  调用这个方法
     */
    @Override
    public void onChildViewAttachedToWindow(@NonNull View view) {
        if(mDrift >0){
            //向上滑
            if(onViewPagerListener !=null){
                //如果是向上滑动的时候  就选中当前itemView下一个item
                onViewPagerListener.onPageSelected(view);
            }
        }else{
            //向下滑
            if(onViewPagerListener !=null){
                //如果是向上滑动的时候  就选中当前itemView下一个item
                onViewPagerListener.onPageSelected(view);
            }
        }
    }

    /**
     * 将Item移除出去的时候  调用这个方法
     */
    @Override
    public void onChildViewDetachedFromWindow(@NonNull View view) {
        Log.e("EEEEEEEEE","22222222222222222");
        if(mDrift >=0){
            //向上滑
            if(onViewPagerListener !=null){
                onViewPagerListener.onPageRelease(view);
            }
        }else{
            //向下滑
            if(onViewPagerListener !=null){
                onViewPagerListener.onPageRelease(view);
            }
        }
    }

    public void setOnViewPagerListener(OnViewPagerListener onViewPagerListener) {
        this.onViewPagerListener = onViewPagerListener;
    }
}

在Activity中初始化接口,releaseVideo方法表示停止播放视频,playVideo方法表示开始播放视频。

    private void initListener() {
        myLayoutManager.setOnViewPagerListener(new OnViewPagerListener() {
            @Override
            public void onPageRelease(View itemView) {
                releaseVideo(itemView);
            }

            @Override
            public void onPageSelected(View itemView) {
                playVideo(itemView);
            }
        });
    }

吸低和吸顶

使用PagerSnapHelper,如下:

 //解决吸顶或者洗低的对象
    private PagerSnapHelper pagerSnapHelper;

    public MyLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
        pagerSnapHelper = new PagerSnapHelper();
    }


    /**
     * 当MyLayoutManager完全放入到RecyclerView中的时候会被调用
     */
    @Override
    public void onAttachedToWindow(RecyclerView view) {
        view.addOnChildAttachStateChangeListener(this);
        pagerSnapHelper.attachToRecyclerView(view);
        super.onAttachedToWindow(view);
    }

  myLayoutManager = new MyLayoutManager(this, OrientationHelper.VERTICAL, false);

解决滑动后播放问题,当滑动停止后播放视频


    /**
     * 监听滑动的状态
     */
    @Override
    public void onScrollStateChanged(int state) {
        switch (state) {
            case RecyclerView.SCROLL_STATE_IDLE:
                //现在拿到的就是当前显示的这个item
                View snapView = pagerSnapHelper.findSnapView(this);
                assert snapView != null;
                if (onViewPagerListener != null) {
                    onViewPagerListener.onPageSelected(snapView);
                }
                break;
        }
        super.onScrollStateChanged(state);
    }

Github:
https://github.com/345166018/AndroidUI/tree/master/HxDouYin

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AndroidRecyclerView是一个用于展示大量数据列表的视图控件,而仿则是模仿界面和交互方式进行开发。在开发仿RecyclerView时,我们可以按照以下步骤进行: 1. 创建RecyclerView和Adapter:首先,我们需要创建一个RecyclerView和一个自定义的Adapter,用于展示数据列表。Adapter负责将数据绑定到RecyclerView上,我们可以在Adapter中重写`onCreateViewHolder`和`onBindViewHolder`方法,分别用于创建列表项的视图和绑定数据。 2. 创建列表项布局:仿的列表项通常包含一个视频播放器和相关的交互按钮,我们可以通过创建一个对应的列表项布局来实现。可以使用FrameLayout来容纳视频播放器和按钮,并设置正确的权重和布局参数。 3. 加载视频数据:仿需要加载大量的视频数据,我们可以使用网络请求库如Retrofit来获取数据,然后将数据传递给Adapter进行展示。 4. 实现视频播放功能:为了实现仿的视频播放功能,我们需要使用一些开源的视频播放库如ExoPlayer或者ijkplayer,并在RecyclerView中的列表项布局中添加播放器视图。在Adapter中,我们可以在列表项被绑定时通过调用播放器的相应方法来实现视频的播放和暂停。 5. 实现列表滑动自动播放功能:仿的一个重要特点是列表滑动到可见区域时自动播放视频,而滑出屏幕后则停止播放。我们可以通过RecyclerView的滑动监听来实现这一功能,当滑动停止时,判断可见区域内的列表项是否包含播放器,如果包含则开始播放,否则停止播放。 6. 实现交互按钮功能:仿的视频列表通常还包含一些交互按钮,如点赞、评论、分享等。我们可以在列表项布局中添加相应的按钮,并设置点击监听器,在按钮点击时执行相应的操作。 通过以上步骤,我们可以实现一个仿RecyclerView,展示大量的视频数据,并实现视频播放、滑动自动播放和交互按钮等功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值