ViewPager的操作
说到ViwePager应该大家都不陌生,它可以结合普通的View也可以结合Fragment一起使用。在此我也就不对它的使用方法进行过多的介绍了。直接开始介绍轮播的方法。
常见的轮播操作
private class ImageAdapter extends PagerAdapter{ private ArrayList<ImageView> viewlist; public ImageAdapter(ArrayList<ImageView> viewlist) {this.viewlist = viewlist; } @Override public int getCount() {//设置成最大,使用户看不到边界return Integer.MAX_VALUE; } ....}
private static class ImageHandler extends Handler{ ... @Override public void handleMessage(Message msg) {super.handleMessage(msg);//检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。if (activity.handler.hasMessages(MSG_UPDATE_IMAGE)){ activity.handler.removeMessages(MSG_UPDATE_IMAGE);}switch (msg.what) { case MSG_UPDATE_IMAGE:currentItem++;activity.viewPager.setCurrentItem(currentItem);//准备下次播放activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);break; case MSG_KEEP_SILENT://只要不发送消息就暂停了break; case MSG_BREAK_SILENT:activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);break; case MSG_PAGE_CHANGED://记录当前的页号,避免播放的时候页面显示不正确。currentItem = msg.arg1;break; default:break;} } ...}以上就是比较常见的轮播图的代码,我只是在网上随便找的。首先它的代码中将PagerAdapter的
getCount()
返回了一个Integer.MAX_VALUE;
它的目的是为了让图片一直的播放下去,但是在一些极限情况下还是会crash的,并且它返回的数量太大了在一定程度上对内存也造成了较大的消耗。其次我们可以看到handler的代码极其的冗杂,不仅多而且逻辑也比较麻烦。 现在我们针对刚才的问题来进行优化for (int i = 0; i < count + 2; i++) { if (i == 0) {// 将最前面一页设置成本来最后的那页Glide.with(context).load(imageTitleBeanList.get(count - 1).getImageUrl()).into(ivImage);tvTitle.setText(imageTitleBeanList.get(count - 1).getTitle()); } else if (i == count + 1) {// 将最后面一页设置成本来最前的那页Glide.with(context).load(imageTitleBeanList.get(0).getImageUrl()).into(ivImage);tvTitle.setText(imageTitleBeanList.get(0).getTitle()); } else {Glide.with(context).load(imageTitleBeanList.get(i - 1).getImageUrl()).into(ivImage);tvTitle.setText(imageTitleBeanList.get(i - 1).getTitle()); } // 将设置好的View添加到View列表中 viewList.add(view);}2)在监听ViewPager的页卡状态改变中,当滑动到第1个页卡时替换成倒数第2个页卡;当滑动到最后一个页卡时替换成第2个页卡。
@Overridepublic void onPageScrollStateChanged(int state) { switch (state) {// 闲置中case ViewPager.SCROLL_STATE_IDLE: // “偷梁换柱” if (vpImageTitle.getCurrentItem() == 0) {vpImageTitle.setCurrentItem(count, false); } else if (vpImageTitle.getCurrentItem() == count + 1) {vpImageTitle.setCurrentItem(1, false); } currentItem = vpImageTitle.getCurrentItem(); break; }}Handler现在就该由RxJava来替代了。
Interval操作符返回一个Observable,它按固定的时间间隔发射一个无限递增的整数序列。
RxJava将这个操作符实现为interval方法。它接受一个表示时间间隔的参数和一个表示时间单位的参数。
Javadoc: interval(long,TimeUnit)
Javadoc: interval(long,TimeUnit,Scheduler)
interval默认在computation调度器上执行。你也可以传递一个可选的Scheduler参数来指定调度器。
用RxJava取代Handler
public void start() { mViewPagerSubscribe = Observable.interval(5, 5, TimeUnit.SECONDS) // 5s的延迟,5s的循环时间.subscribeOn(AndroidSchedulers.mainThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Long>() { @Override public void call(Long aLong) {// 进行轮播操作if (mWeeklyMovieInfos != null && mWeeklyMovieInfos.size() > 0 && isAutoPlay) { mCurrentPage++; mWeeklyViewPager.setCurrentItem(mCurrentPage);} }});}为了更好的用户体验,在用户进行滑动操作的时候,应该停止自动轮播
mPager.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //监听ViewPager的触摸事件,当用户按下的时候取消注册,当用户手抬起的时候再注册switch (event.getAction()){ case MotionEvent.ACTION_DOWN:stop();break; case MotionEvent.ACTION_UP:start();break; }return false; }});public void stop() { if(mViewPagerSubscribe.isUnsubscribed()) { mViewPagerSubscribe.unsubscribe(); }}总结