最近遇到一个图片视频轮播的需求,网上看了很多都差不多。
1.需要一个viewpager 将他设置成无限循环的
2.需要一个 定时器的功能,在指定的时间去切换item
3.videoview 相关的api 以及缓存和播放功能的实现
第一个功能实现,网上很多,大都在 头尾加两个过度界面就好了
mViewPager.setOnPageChangeListener(this);
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mCurrentItem = position;
Log.i("vp", "onPageSelected,mCurrentItem=" + mCurrentItem);
}
@Override
public void onPageScrollStateChanged(int state) {
switch (state) {
case SCROLL_STATE_IDLE:
Log.i("vp", "SCROLL_STATE_IDLE,mCurrentItem=" + mCurrentItem);
if (mCurrentItem == 0) {
mViewPager.setCurrentItem(count, false);
} else if (mCurrentItem == count + 1) {
mViewPager.setCurrentItem(1, false);
}
break;
case SCROLL_STATE_DRAGGING:
Log.i("vp", "SCROLL_STATE_DRAGGING,mCurrentItem=" + mCurrentItem);
if (mCurrentItem == count + 1) {
mViewPager.setCurrentItem(1, false);
} else if (mCurrentItem == 0) {
mViewPager.setCurrentItem(count, false);
}
break;
default:
case SCROLL_STATE_SETTLING:
break;
}
}
public static class AutoScrollPagerAdapter extends PagerAdapter {
private List mModelList;
private BannerLoader mBannerLoader;
private List mViewList = new ArrayList<>();
public AutoScrollPagerAdapter(List modelList, BannerLoader bannerLoader, Context context) {
mModelList = modelList;
//头尾加两个过度元素
if (modelList.size() > 1) {
mModelList.add(0, modelList.get(modelList.size() - 1));
mModelList.add(modelList.get(1));
}
mBannerLoader = bannerLoader;
for (int i = 0; i < mModelList.size(); i++) {
View view = mBannerLoader.createView(context, mModelList.get(i));
mViewList.add(view);
}
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = mViewList.get(position);
mBannerLoader.loadContent(mModelList.get(position), view);
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
//。。。其他省略
}
大致以上实现无限循环的功能 就完成了
2.直接handler 解决
public abstract class AutoScrollTask implements Runnable {
@Override
public void run() {
setCurrent(getCurrent());
}
public abstract int getCurrent();
public abstract void setCurrent(int position);
}
定义一个task 通过handler 来实现
public void startAutoPlay() {
if (mAutoScrollPagerAdapter == null) {
throw new IllegalStateException("must call set setDataList first");
}
if (mScrollTask != null) {
mHandler.removeCallbacks(mScrollTask);
} else {
mScrollTask = new AutoScrollTask() {
@Override
public int getCurrent() {
return mCurrentItem % (count + 1) + 1;
}
@Override
public void setCurrent(int position) {
mViewPager.setCurrentItem(position);
mHandler.postDelayed(mScrollTask, mAutoScrollPagerAdapter.getItemDelayTime(position));
}
};
}
mHandler.postDelayed(mScrollTask, mAutoScrollPagerAdapter.getItemDelayTime(mCurrentItem));
}
这样第二个功能就没问题了
感觉没毛病,但是这个时候,视频的前一个页面也跟着一起黑屏了,非常不理解。
之后就是无止尽的调试,最终看到了这个东西
这个BannerViewPager 跟系统的是一样的,罪魁祸首就是 clipChildren 默认是true ,这个属性是设置 是否限制子view 在父view 的范围内,去掉之后就一切正常了。
3.视频边缓存边播放,
https://github.com/danikula/AndroidVideoCache 可以看看这个库,我没研究 卡在上面个bug 一天,拿别人的东西原样跑没问题,搬到自己写的demo里面就各种奇怪的问题。