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

发布了391 篇原创文章 · 获赞 58 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/hongxue8888/article/details/104109232
今日推荐