仿抖音上下滑动播放视频

怎甘沉沦 提交于 2020-03-10 22:14:17

不少朋友对短视频,上下滑动播放视频效果比较比较感兴趣,今天看看这个案例。

1、效果图:

讲下大概思路,使用Recycleview配合自定义LinearLayoutManager来实现这个功能,这里着重说下自定义LinearLayoutManager的实现可以看到每当下一个item滑入屏幕时,上面的item会继续播放视频,而滑入的item只有当全部进入屏幕才会播放,而且当手指抬起时,当前item会根据滑动的距离相应的自动滑入滑出,针对这种情形,就会想到使用SnapHelper

RecyclerView在24.2.0版本中新增了SnapHelper这个辅助类,用于辅助RecyclerView在滚动结束时将Item对齐到某个位置。特别是列表横向滑动时,很多时候不会让列表滑到任意位置,而是会有一定的规则限制,这时候就可以通过SnapHelper来定义对齐规则了。

SnapHelper是一个抽象类,官方提供了一个LinearSnapHelper的子类,可以让RecyclerView滚动停止时相应的Item停留中间位置。25.1.0版本中官方又提供了一个PagerSnapHelper的子类,可以使RecyclerView像ViewPager一样的效果,一次只能滑一页,而且居中显示,也就是说使用SnapHelper可以帮助RecyclerView滑动完成后进行对齐操作,让item的侧边对齐或者居中对齐,这样实现上下滑动进行视频切换。这里有SnapHelper的详解

2、正式撸代码:
1.首先定义一个接口,用来执行item的相关操作

public interface OnViewPagerListener {  
    /*初始化完成*/  
    void onInitComplete();  
    /*释放的监听*/  
    void onPageRelease(boolean isNext, int position);  
    /*选中的监听以及判断是否滑动到底部*/  
    void onPageSelected(int position, boolean isBottom);  
}  

2.继承LinearLayoutManager ,对滑入滑出的item回调1中接口里面的方法

import android.content.Context;  
import android.support.annotation.NonNull;  
import android.support.v7.widget.LinearLayoutManager;  
import android.support.v7.widget.PagerSnapHelper;  
import android.support.v7.widget.RecyclerView;  
import android.view.View;

public class MyLayoutManager extends LinearLayoutManager implements RecyclerView.OnChildAttachStateChangeListener {  
    private int mDrift;//位移,用来判断移动方向

    private PagerSnapHelper mPagerSnapHelper;  
    private OnViewPagerListener mOnViewPagerListener;

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

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

    @Override  
    public void onAttachedToWindow(RecyclerView view) {

        view.addOnChildAttachStateChangeListener(this);  
        mPagerSnapHelper.attachToRecyclerView(view);  
        super.onAttachedToWindow(view);  
    }  
//当Item添加进来了  调用这个方法

    //  
    @Override  
    public void onChildViewAttachedToWindow(@NonNull View view) {  
//        播放视频操作 即将要播放的是上一个视频 还是下一个视频  
        int position = getPosition(view);  
        if (0 == position) {  
            if (mOnViewPagerListener != null) {  
                mOnViewPagerListener.onPageSelected(getPosition(view), false);  
            }

        }  
    }

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

    @Override  
    public void onScrollStateChanged(int state) {  
        switch (state) {  
            case RecyclerView.SCROLL\_STATE\_IDLE:  
                View view = mPagerSnapHelper.findSnapView(this);  
                int position = getPosition(view);  
                if (mOnViewPagerListener != null) {  
                    mOnViewPagerListener.onPageSelected(position, position == getItemCount() - 1);

                }  
//                postion  ---回调 ----》播放

  
                break;  
        }  
        super.onScrollStateChanged(state);  
    }

    @Override  
    public void onChildViewDetachedFromWindow(@NonNull View view) {  
//暂停播放操作  
        if (mDrift >= 0) {  
            if (mOnViewPagerListener != null)  
                mOnViewPagerListener.onPageRelease(true, getPosition(view));  
        } else {  
            if (mOnViewPagerListener != null)  
                mOnViewPagerListener.onPageRelease(false, getPosition(view));  
        }  
    }

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

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

3.接下来就是正常使用recycleview了 配合原生VideoView 播放视频,切换时先用一张截图盖住视频,视频渲染成功再隐藏截图,感觉上是无缝切换(这里是原生播放器初始加载视频会黑屏,如果用更高级的播放器可能不会有这个问题)

import android.annotation.TargetApi;  
import android.content.Context;  
import android.media.MediaPlayer;  
import android.net.Uri;  
import android.os.Build;  
import android.os.Bundle;  
import android.support.v7.app.AppCompatActivity;  
import android.support.v7.widget.OrientationHelper;  
import android.support.v7.widget.RecyclerView;  
import android.util.Log;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.ViewGroup;  
import android.widget.ImageView;  
import android.widget.RelativeLayout;  
import android.widget.VideoView;

  
public class MainActivity extends AppCompatActivity {  
    private static final String TAG = "douyin";  
    private RecyclerView mRecyclerView;  
    private MyAdapter mAdapter;  
    MyLayoutManager2 myLayoutManager;

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        initView();  
        initListener();  
    }

    private void initView() {  
        mRecyclerView = findViewById(R.id.recycler);  
        myLayoutManager = new MyLayoutManager2(this, OrientationHelper.VERTICAL, false);

        mAdapter = new MyAdapter(this);  
        mRecyclerView.setLayoutManager(myLayoutManager);  
        mRecyclerView.setAdapter(mAdapter);

    }

    private void initListener() {  
        myLayoutManager.setOnViewPagerListener(new OnViewPagerListener() {  
            @Override  
            public void onInitComplete() {

            }

            @Override  
            public void onPageRelease(boolean isNext, int position) {  
                Log.e(TAG, "释放位置:" + position + " 下一页:" + isNext);  
                int index = 0;  
                if (isNext) {  
                    index = 0;  
                } else {  
                    index = 1;  
                }  
                releaseVideo(index);  
            }

            @Override  
            public void onPageSelected(int position, boolean bottom) {  
                Log.e(TAG, "选择位置:" + position + " 下一页:" + bottom);

                playVideo(0);  
            }  
        });  
    }

    class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {  
        private int\[\] imgs = {R.mipmap.img\_video\_1, R.mipmap.img\_video\_2, R.mipmap.img\_video\_3, R.mipmap.img\_video\_4, R.mipmap.img\_video\_5, R.mipmap.img\_video\_6, R.mipmap.img\_video\_7, R.mipmap.img\_video\_8};  
        private int\[\] videos = {R.raw.video\_1, R.raw.video\_2, R.raw.video\_3, R.raw.video\_4, R.raw.video\_5, R.raw.video\_6, R.raw.video\_7, R.raw.video\_8};  
        private int index = 0;  
        private Context mContext;

        public MyAdapter(Context context) {  
            this.mContext = context;  
        }

  
        @Override  
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item\_view\_pager, parent, false);  
            return new ViewHolder(view);  
        }

        @Override  
        public void onBindViewHolder(ViewHolder holder, int position) {  
            holder.img_thumb.setImageResource(imgs\[index\]);  
            holder.videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + videos\[index\]));  
            index++;  
            if (index >= 7) {  
                index = 0;  
            }  
        }

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

        public 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);  
            }  
        }  
    }

    private void releaseVideo(int index) {  
        View itemView = mRecyclerView.getChildAt(index);  
        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(int position) {  
        View itemView = mRecyclerView.getChildAt(position);  
        final FullWindowVideoView 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.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {  
            @Override  
            public void onPrepared(MediaPlayer mp) {

            }  
        });  
        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.start();

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

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

}  

原创作者:庞哈哈哈12138,原文:https://www.jianshu.com/p/3a043cd4eb1f

欢迎关注我的微信公众号「码农突围」,分享Python、Java、大数据、机器学习、人工智能等技术,关注码农技术提升•职场突围•思维跃迁,20万+码农成长充电第一站,陪有梦想的你一起成长。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!