美文网首页
仿抖音滑动播放小视频

仿抖音滑动播放小视频

作者: 放肆滴微笑 | 来源:发表于2019-12-06 16:41 被阅读0次

需求:上下滑动的控件,还能播放视频,能播放N条,这样就涉及到需要给滑动后的控件回收,所以用RecyclerView。

实现原理:
1、在滑动过程中,进行监听item的进入和移出,并进行播放暂停
2、滑动过程中,item只能显示一个视频,需要达到item滑动吸顶、吸底
3、当滑动停止后,当前item要进行播放

所用知识:
item进入和移出,需要RecyclerView.addOnChildAttachStateChangeListener监听,

吸顶,吸底,需要 PagerSnapHelper,只需要绑定到RecyclerView上就可以了

在LayoutManager中进行滑动监听,所以重写MyLayoutManager,
先进行绑定到RecyclerView上,再做item进入移出监听

public class MyLayoutManager extends LinearLayoutManager implements RecyclerView.OnChildAttachStateChangeListener {
    // 判断上滑还是下滑
    private int mDrift;

    private OnViewPageListener onViewPageListener;

    // 解决吸顶 吸底的效果
    private PagerSnapHelper pagerSnapHelper;

    public MyLayoutManager(Context context) {
        this(context, OrientationHelper.VERTICAL, false);
    }
    //reverseLayout 来判断 RecyclerView数据滑动方向的正反
    public MyLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
        pagerSnapHelper = new PagerSnapHelper();
    }

    public void setOnViewPageListener(OnViewPageListener onViewPageListener) {
        this.onViewPageListener = onViewPageListener;
    }

    /**
     * 当layoutManager 完全放 如到RecyclerView中
     *
     * @param view
     */
    @Override
    public void onAttachedToWindow(RecyclerView view) {
        super.onAttachedToWindow(view);
        // 监听 item 状态改变
        view.addOnChildAttachStateChangeListener(this);
        // 依附到 RecyclerView 上
        pagerSnapHelper.attachToRecyclerView(view);
    }

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

    /**
     * 设置可以滑动,true 可以滑动,flase 不能滑动
     *
     * @return
     */
    @Override
    public boolean canScrollVertically() {
        return true;
    }

    @Override
    public void onScrollStateChanged(int state) {
        switch (state) {
            case RecyclerView.SCROLL_STATE_IDLE:
                View snapView = pagerSnapHelper.findSnapView(this);
                if (snapView != null && onViewPageListener != null) {
                    onViewPageListener.onSelectPage(snapView);
                }
                break;
        }
        super.onScrollStateChanged(state);
    }

    /**
     * 当 item 进入 页面
     * 判断上滑,还是下滑 大于0 上滑
     *
     * @param view
     */
    @Override
    public void onChildViewAttachedToWindow(@NonNull View view) {
//        if (mDrift > 0) {
//            if (onViewPageListener != null) {
//                onViewPageListener.onSelectPage(view);
//            }
//        } else {
//            if (onViewPageListener != null) {
//                onViewPageListener.onSelectPage(view);
//            }
//        }

        if (onViewPageListener != null) {
            onViewPageListener.onSelectPage(view);
        }
    }

    /**
     * 当 item 移除 页面
     * 这个和进入不是成对出现,因为item进入只要有一点就会调用,
     * 移除需要全部移除才调用
     *
     * @param view
     */
    @Override
    public void onChildViewDetachedFromWindow(@NonNull View view) {
        if (onViewPageListener != null) {
            onViewPageListener.onStopPage(view);
        }
    }
}

播放监听

public interface OnViewPageListener {
    // 停止播放
    void onStopPage(View view);

    // 开始播放
    void onSelectPage(View view);
}

Adapter

public class MyDouYinAdapter extends RecyclerView.Adapter<MyDouYinAdapter.ViewHolder> {
    private Context context;
    private int[] imgs = {R.mipmap.img_video_1, R.mipmap.img_video_2, R.mipmap.img_video_1, R.mipmap.img_video_2, R.mipmap.img_video_1, R.mipmap.img_video_2};
    private int[] videos = {R.raw.video_1, R.raw.video_2, R.raw.video_1, R.raw.video_2, R.raw.video_1, R.raw.video_2};

    public MyDouYinAdapter(Context context) {
        this.context = context;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_douyin, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        holder.img_thumb.setImageResource(imgs[position]);
        holder.videoView.setVideoURI(Uri.parse("android.resource://" + context.getPackageName() + "/" + videos[position]));
    }

    @Override
    public int getItemCount() {
        return 4;
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        ImageView img_thumb;
        VideoView videoView;
        ImageView img_play;
        RelativeLayout rootView;

        public ViewHolder(View itemView) {
            super(itemView);
            img_thumb = itemView.findViewById(R.id.img_thumb);
            videoView = itemView.findViewById(R.id.video_view);
            img_play = itemView.findViewById(R.id.img_play);
            rootView = itemView.findViewById(R.id.root_view);
        }
    }
}

Activity进行绑定

public class DouYinActivity extends Activity implements OnViewPageListener {
    private RecyclerView rv;
    private MyDouYinAdapter adapter;
    private MyLayoutManager myLayoutManager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_douyin);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //获取到状态栏设置的两条属性
            int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
            int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
            //在4.4之后又有两种情况  第一种 4.4-5.0   第二种 5.0以上
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                //第二种 5.0以上
                Window window = getWindow();
                WindowManager.LayoutParams attributes = window.getAttributes();
                attributes.flags |= flagTranslucentNavigation;
                window.setAttributes(attributes);
                window.setStatusBarColor(0);
            } else {
                //第一种 4.4-5.0
                Window window = getWindow();
                WindowManager.LayoutParams attributes = window.getAttributes();
                attributes.flags |= flagTranslucentStatus | flagTranslucentNavigation;
                window.setAttributes(attributes);
            }
        }

        rv = findViewById(R.id.rv);

        myLayoutManager = new MyLayoutManager(this);
        myLayoutManager.setOnViewPageListener(this);
        rv.setLayoutManager(myLayoutManager);


        adapter = new MyDouYinAdapter(this);
        rv.setAdapter(adapter);
    }

    @Override
    public void onStopPage(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();
    }

    @Override
    public void onSelectPage(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;
                }
            }
        });
    }
}

相关文章

网友评论

      本文标题:仿抖音滑动播放小视频

      本文链接:https://www.haomeiwen.com/subject/beyegctx.html