仿抖音滑动播放小视频
2019-12-06 本文已影响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;
}
}
});
}
}