主要介绍如何实现ViewPager自动播放,循环滚动的效果及使用。顺便解决ViewPager嵌套(ViewPager inside ViewPager)影响触摸滑动及ViewPager滑动速度设置问题。
项目已开源Android Auto Scroll ViewPager@Github,欢迎star和fork。
更多自动滚动轮播的开源项目可见:自动滚动 ViewPager。
Demo APK 可以方便的查看效果,在各大应用商店搜索 trinea android 下载即可,如:Google Play。
示例代码地址见AutoScrollViewPagerDemo,效果图如下:
1、实现
没有通过ScheduledExecutorService或Timer定期执行某个任务实现,而是简单的通过handler发送消息去完成一次滚动,在完成一次滚动后发送另外一个delay的滚动消息,如此循环实现。自动滚动部分核心代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public void startAutoScroll() { isAutoScroll = true; sendScrollMessage(interval); } private void sendScrollMessage(long delayTimeInMills) { /** remove messages before, keeps one message is running at most **/ handler.removeMessages(SCROLL_WHAT); handler.sendEmptyMessageDelayed(SCROLL_WHAT, delayTimeInMills); } private class MyHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case SCROLL_WHAT: scrollOnce(); sendScrollMessage(interval); break; } } } |
至于ViewPager嵌套引起子ViewPager无法触摸问题是通过在子ViewPager的onTouchEvent中添加
1 |
getParent().requestDisallowInterceptTouchEvent(true); |
禁止父控件对touch event做intercept解决的。
ViewPager滑动速度的设置是通过反射的方式重新设置ViewPager的Scroller,改变Scroller的startScroll的间隔时间完成的。调用setScrollDurationFactor(double)即可。
2、使用
(1) 引入公共库
引入Android Auto Scroll ViewPager@Github作为你项目的library(如何拉取代码及添加公共库)。
(2) 调用
仅需简单两步:
a. 布局定义
1 2 3 4 |
<cn.trinea.android.view.autoscrollviewpager.AutoScrollViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="wrap_content" /> |
代替一般的ViewPager定义
b. 启动ViewPager自动滚动
startAutoScroll() 启动自动滚动
stopAutoScroll() 停止自动滚动
3、设置
setInterval(long) 设置自动滚动的间隔时间,单位为毫秒
setDirection(int) 设置自动滚动的方向,默认向右
setCycle(boolean) 是否自动循环轮播,默认为true
setScrollDurationFactor(double) 设置ViewPager滑动动画间隔时间的倍率,达到减慢动画或改变动画速度的效果
setStopScrollWhenTouch(boolean) 当手指碰到ViewPager时是否停止自动滚动,默认为true
setSlideBorderMode(int) 滑动到第一个或最后一个Item的处理方式,支持没有任何操作、轮播以及传递到父View三种模式
setBorderAnimation(boolean) 设置循环滚动时滑动到从边缘滚动到下一个是否需要动画,默认为true
4、其他
(1) 指示器,圆形或是方形指示器请配合ViewPagerIndicator使用
(2)无限循环,如果希望在最后一张继续播放第一张而不是退回到第一张,请参考AutoScrollViewPagerSingleDemo.java,注意这个特性不能和 ViewPagerIndicator 使用
(3)更多自动滚动轮播的开源项目可见:自动滚动 ViewPager
容易假死啊
无线循环不能和 ViewPagerIndicator 同时使用
没有用ViewPagerIndicator,只用了AutoScrollViewPager,这代码viewPager.setCurrentItem(Integer.MAX_VALUE / 2 – Integer.MAX_VALUE / 2 % ListUtils.getSize(imageIdList));就会出现假死,还有就是调用setCurrentItem( getCurrentItem()+n)n>1也会假死的。
直接运行我的示例代码
Pingback: Android开源项目分类汇总 | Cloud Technology
我有写过一个handler专门用来轮询的,其实不需要自己重写Viewpager吧
嗯,原理一样,只是这些加上触摸停止、级联滑动、速度控制等特性放到了一起
楼主,好像setInfiniteLoop(true)之后程序假死,有解决办法么?
不能与 ViewPagerIndicator 同时使用
按照你AutoScrollViewPagerDemo里面的代码写的,但是到最后一张的时候会调至第一张,感觉很不友好,mAutoPagerImage.setVisibility(View.VISIBLE); indexText = (TextView) rootView.findViewById(R.id.view_pager_index); mAutoPagerImage.setAdapter(new ImagePagerAdapter(getActivity(), imageList).setInfiniteLoop(true)); mAutoPagerImage.setOnPageChangeListener(this); mAutoPagerImage.setInterval(2000); mAutoPagerImage.startAutoScroll(); mAutoPagerImage.setScrollDurationFactor(3.5);这是代码,这是图片的List:private ArrayList imageList;请问能怎么解决呢、
请看 Demo 无线循环样式
解决了,这里提醒一下各位如果设置了最大值 要把.setInfiniteLoop(true) 去掉 要不然会假死。。。问了楼主好多天也不告诉我 我终于自己发现了。。。
求教楼主后面要%一个size是什么意思? viewPager.setCurrentItem(Integer.MAX_VALUE / 2 – Integer.MAX_VALUE / 2 % ListUtils.getSize(imageIdList));
楼主 我的 onclick时间和楼主的ontouchevent有冲突怎么办,无论如何也不toastviewPager.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getActivity(),”is clicked”,Toast.LENGTH_SHORT).show(); }
请问,我吧这个viewpager用addheaderview 放到了listview中,可以左右滑动图片但是不能上下滑动,我的意思是我的listview有下拉刷新功能,这个怎么办?
http://www.trinea.cn/android/touch-event-delivery-mechanism/
谢谢!知道了好多
LZ请教一下 手动滑到最后一页 想继续滑到第一页 好像不行 设置了setSlideBorderMode(int)行不通
我配合了viewpagerindicator
可以是可以最后一个滑动到第一个 动画过度很快。
嗯,那个模式有Bug