實作的思路是采用RecyclerView 的多布局,再配合PageSnapeHelper這個類實作類似ViewPager一樣的效果,涉及到視訊播放本次使用的是餃子播放器,也可以使用其他播放器,隻要實作效果就可以
布局隻有一個RecyclerView 就不貼代碼了
在activity中初始化RecyclerView
layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
bannerRv.setLayoutManager(layoutManager);
if (multiAdapter == null) {
multiAdapter = new JiFenGoodsDetailTypesAdapter(mList);
}
snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(bannerRv);
bannerRv.setAdapter(multiAdapter);
關于 Adapter使用的BaseRecyclerViewAdapterHelper開源封裝庫,如下
ublic class JiFenGoodsDetailTypesAdapter extends BaseMultiItemQuickAdapter<VideoMultyItem, BaseViewHolder>{
/**
* Same as QuickAdapter#QuickAdapter(Context,int) but with
* some initialization data.
*
* @param data A new list is created out of this one to avoid mutable list
*/
public JiFenGoodsDetailTypesAdapter(List<VideoMultyItem> data) {
super(data);
addItemType(1, R.layout.banner_video);
addItemType(2, R.layout.banner_image);
}
@Override
protected void convert(BaseViewHolder helper, VideoMultyItem item) {
helper.setText(R.id.item_number_tv,helper.getLayoutPosition()+1+"/"+getItemCount());
switch (item.getItemType()){
case 1:
//視訊
JzvdStd jzvdStd = helper.getView(R.id.player);
//去掉
jzvdStd.setUp(item.getUrl()+"", "");
Glide.with(mContext).load(item.getCoverUrl()).into(jzvdStd.thumbImageView);
jzvdStd.startVideo();
break;
case 2:
ImageView imageView = helper.getView(R.id.image);
Glide.with(mContext).load(item.getUrl()).into(imageView);
break;
default:
break;
}
}
}
其中實體類VideoMultyItem 要實作MultiItemEntity 來傳回對應的type,用于實作多布局,代碼如下
public class VideoMultyItem implements MultiItemEntity {
private String url;
//1 是視訊 2 是商品
private int flag;
private String coverUrl;
public String getCoverUrl() {
return coverUrl;
}
public void setCoverUrl(String coverUrl) {
this.coverUrl = coverUrl;
}
public VideoMultyItem(String url, int flag) {
this.url = url;
this.flag = flag;
}
public String getUrl() {
return url;
}
public int getFlag() {
return flag;
}
@Override
public int getItemType() {
return flag;
}
}
其中banner_video 和banner_image 的布局也貼出來
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<cn.jzvd.JzvdStd
android:id="@+id/player"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1/2"
android:textColor="@color/white"
android:background="@drawable/red_corner_dp10_bg"
android:paddingLeft="@dimen/dp_10"
android:paddingRight="@dimen/dp_10"
android:paddingTop="@dimen/dp_1"
android:paddingBottom="@dimen/dp_1"
android:id="@+id/item_number_tv"
android:textSize="@dimen/sp_12"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="@dimen/dp_12"
android:layout_marginBottom="@dimen/dp_12"
/>
</RelativeLayout>
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:id="@+id/image"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1/2"
android:textColor="@color/white"
android:background="@drawable/red_corner_dp10_bg"
android:paddingLeft="@dimen/dp_8"
android:paddingRight="@dimen/dp_8"
android:paddingTop="@dimen/dp_2"
android:paddingBottom="@dimen/dp_2"
android:id="@+id/item_number_tv"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="@dimen/dp_12"
android:layout_marginBottom="@dimen/dp_12"
/>
</RelativeLayout>
由于在滑動的時候要求自動播放是以還需要對Recyclerview的滑動監聽做一下處理,在滑動到視訊頁的時候自動播放,滑出的時候停止播放,代碼如下
bannerRv.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
switch (newState) {
case RecyclerView.SCROLL_STATE_IDLE:
//停止滾動
autoPlay(recyclerView);
break;
case RecyclerView.SCROLL_STATE_DRAGGING:
//拖動
break;
case RecyclerView.SCROLL_STATE_SETTLING:
//慣性滑動
Jzvd.releaseAllVideos();
break;
default:
break;
}
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
autoplay的代碼
private void autoPlay(RecyclerView recyclerView) {
View view = snapHelper.findSnapView(layoutManager);
if (view != null) {
if (view instanceof RelativeLayout) {
Jzvd.releaseAllVideos();
} else {
BaseViewHolder viewHolder = (BaseViewHolder) recyclerView.getChildViewHolder(view);
if (viewHolder != null) {
JzvdStd myVideoPlayer = viewHolder.getView(R.id.player);
myVideoPlayer.startVideo();
}
}
}
}
圖檔要求點選的時候全屏放大,使用的是XPopup
multiAdapter.setOnItemClickListener((adapter, view, position) -> {
VideoMultyItem o = (VideoMultyItem) adapter.getData().get(position);
if (o.getFlag() == 2) {
//圖檔點選則放大
ImageView imageView = (ImageView) adapter.getViewByPosition(bannerRv, position, R.id.image);
//bannner 點選
new XPopup.Builder(JieFenGoodsDetailActivity.this)
.asImageViewer(imageView, o.getUrl(), new XpopImageLoader()).show();
}
});
這樣就基本實作了視訊圖檔混播,還有視訊緩存的功能的還沒加上,視訊緩存可以使用videocache
後續加上了再修改