主要介绍如何实现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
setStopScrollWhenTouch(true) :小米2S、三星GT-I8150测试发现无效果,还是会自动滑动。
这个表示手指在ViewPager按下的时候停止滑动,默认就是这样的。我在小米2s上测试的没问题。你可以试下demo有没有问题 https://play.google.com/store/apps/details?id=cn.trinea.android.demo
demo经测试木有问题~ 自己写的时候就有问题了,上代码: AutoScrollViewPager viewPager = (AutoScrollViewPager) view.findViewById(R.id.vp_banner);viewPager.setAdapter(new BannerPagerAdapter(viewPager, banners));viewPager.setCycle(true);viewPager.setDirection(AutoScrollViewPager.RIGHT);viewPager.setInterval(4000);viewPager.setSlideBorderMode(AutoScrollViewPager.SLIDE_BORDER_MODE_CYCLE);viewPager.setStopScrollWhenTouch(true);viewPager.setCurrentItem(0, true); viewPager.startAutoScroll();请楼主过目,看是啥问题?多谢啦~
怎样控制图片轮播不与侧滑菜单冲突呢
你用的是什么侧滑菜单
使用的是网上写的一个简单的侧滑,我现在加了一个判断,解决了这个问题:当侧滑菜单打开的时候,图片轮播停止,侧滑菜单关闭的时候,图片轮播开始。
这个setStopScrollWhenTouch(boolean) 当手指碰到ViewPager时是否停止自动滚动,默认为true,不起作用,我手指放上去还是自动滚动,还有为什么向右滚动到最后一个了在返回到第一个却是向左滚动的,很别扭
第一个问题,你的测试环境是什么样的,我的demo是否有问题第二个问题你可以通过adapter的getcount返回无限大解决
第二个设置为无穷大会引发一些问题。1.用户无限滑动会导致viewpager里面的view没有被回收或者重用 2.再附加上handler隔一段时间发一个消息,一段时间后程序就会出现假死现象。我之前遇到过,后面就放弃了,当然也有可能是我的办法不对。
用这个https://github.com/JakeWharton/salvage 缓存就可以了
楼主,你这个ViewPage里面自带有图片右下角那个圆点吗??
不带,那是另外一个开源项目
楼主好,一直对楼主的博文都非常膜拜,今天在项目中用了轮播的viewpager,总是时不时的报错,具体错误信息如下:java.lang.NullPointerException at android.support.v4.app.Fragment.setUserVisibleHint(Fragment.java:801) at android.support.v4.app.FragmentStatePagerAdapter.setPrimaryItem(FragmentStatePagerAdapter.java:152) at android.support.v4.view.ViewPager.populate(ViewPager.java:1009) at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:522) at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:494) at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:486) at cn.trinea.android.view.autoscrollviewpager.AutoScrollViewPager.scrollOnce(AutoScrollViewPager.java:157) at cn.trinea.android.view.autoscrollviewpager.AutoScrollViewPager$MyHandler.handleMessage(AutoScrollViewPager.java:220) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:4945) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(Native Method)
具体是在什么时候?自动滚动到最后一个?
不固定吧,偶尔性的,我加了try…catch,有时间看看你的代码
很奇怪,这个实际上我用了半年多了,一直没什么问题,最近才开放的。你是不是adapter经常变
首选感谢楼主开源精神,弱弱的问一下楼主,viewpager滑动过程老感觉他滑动特别快。有没有
setScrollDurationFactor
可能我没有表达清楚。我的意思是。viewpager滑动到最后一个时候。然后接着手动滑动。按正常逻辑是滑动到第一个。但是轻轻一滑他就到了第二个了
嗯,滑动轮播这块现在是有Bug的。可以setSlideBorderMode设置成其他Mode
很棒,每次来都会看到新东西
你用过MAT分析工具吗,能不能就MAT写篇文章出来。
google这类专业介绍很多
有时间弄一个wheelview控件么?目前开源的那个不太好,好几次都想给它重写一个
https://github.com/Trinea/android-open-project 这里面的都不行吗?我现在对这个控件没什么需求,你可以搞一个,帮你宣传
请问博主使用Android Auto Scroll ViewPager和其他方法(Timer,ScheduledExecutorService,Thread等),较其性能或者其他方面有何优势呢?能否谈谈。还有如果要实现自动滑动,且滑动中实现滑动动画,可以实现么?如何实现或者思路呢?
和其他方法相比的性能相差无几,而直接用handler的话逻辑简单。不过之前有对比过ScheduledExecutorService比Timeer的性能好滑动中的动画的话,可以参考https://github.com/Trinea/android-open-project#%E5%9B%9Bviewpager-gallery 这里面的2和5
楼主,我觉得自动滑动(调用setCurrentItem)时的动画不够平滑,有点闪,有没有什么解决办法?
抱歉,找到答案了
setScrollDurationFactor