如何实现一个抖音首页的沉浸式视频播放效果
01.疑问
怎么实现一个顺畅的类似抖音的沉浸式播放效果
02.方案
方案1:viewpager+复用,低端机教卡
方案2:recycleview,比较顺畅
方案3:viewpager2
03.实现
public class TestActivity extends BaseActivity {
LinearLayoutManager mLinearLayoutManager;
int preShowPosition;
TestListAdapter madapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_test_test);
RecyclerView recyclerView = findViewById(R.id.rv);
madapter = new TestListAdapter(this);
ArrayList<Object> objects = new ArrayList<>();
objects.add("http://vjs.zencdn.net/v/oceans.mp4");
objects.add("http://vjs.zencdn.net/v/oceans.mp4");
objects.add("http://vjs.zencdn.net/v/oceans.mp4");
objects.add("http://vjs.zencdn.net/v/oceans.mp4");
objects.add("http://vjs.zencdn.net/v/oceans.mp4");
new PagerSnapHelper().attachToRecyclerView(recyclerView);
mLinearLayoutManager = new LinearLayoutManager(mContext) {
public boolean canScrollVertically() {
return super.canScrollVertically();
}
};
recyclerView.setLayoutManager(mLinearLayoutManager);
recyclerView.setAdapter(madapter);
madapter.setNewData(objects);
recyclerView.addOnScrollListener(new MyScrollListener());
}
class MyScrollListener extends RecyclerView.OnScrollListener {
public MyScrollListener() {
}
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == 0
&& mLinearLayoutManager.findFirstVisibleItemPosition() != -1) {
int position = mLinearLayoutManager.findFirstVisibleItemPosition();
if (preShowPosition < position) {
preShowPosition = position;
if (madapter.getData().size() > position + 1) {
// 对上一个下一个做预处理
}
} else if (preShowPosition > position) {
preShowPosition = position;
if (position != 0) {
}
}
TestBlock block =
(TestBlock) mLinearLayoutManager.findViewByPosition(position);
block.startVideo();
}
}
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
}
}
public class TestBlock extends FrameLayout {
private Context mContext;
private XXVideoView XXVideoView;
public TestBlock(@NonNull Context context) {
this(context, null);
}
public TestBlock(@NonNull Context context,
@Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
mContext = context;
inflate(mContext, R.layout.layout_sticky_header_view, this);
setLayoutParams(
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
XXVideoView = findViewById(R.id.tv_sticky_header_view);
XXVideoView.setLoop(true);
XXVideoView.setAlpha(1f);
}
public void setData(String url) {
XXVideoView.setVideoPath(url);
}
public void startVideo() {
XXVideoView.start();
}
}
public class TestListAdapter extends BaseTypeAdapter<Object> {
private final int TYPE_SECTION_DATE = -1;
private Activity mActivity;
public TestListAdapter(Activity activity) {
this.mActivity = activity;
}
@Override
protected View createView(int type, ViewGroup parent) {
View ret = null;
switch (type) {
case TYPE_SECTION_DATE:
ret = new TestBlock(mActivity);
break;
}
return ret;
}
@Override
protected int getType(int position, Object data) {
if (data instanceof String) {
return TYPE_SECTION_DATE;
} else {
return TYPE_COMMOM;
}
}
@Override
protected void bindData(BaseViewHolder holder, Object data, int position, int type) {
switch (type) {
case TYPE_SECTION_DATE:
TestBlock block = (TestBlock) holder.getConvertView();
block.setData("http://vjs.zencdn.net/v/oceans.mp4");
break;
}
}
}
当然只是实现了,简单的效果,各种预加载等等并未处理
04.参考资料
让你明明白白的使用RecyclerView——SnapHelper详解
https://www.jianshu.com/p/e54db232df62
你们要的抖音效果来了
http://www.10tiao.com/html/169/201806/2650825600/1.html
viewpager2原理和使用
https://www.jianshu.com/p/6d46c89069f8
这个目前还不稳定
来源:https://blog.csdn.net/a910626/article/details/101075004