ViewPager的主要作用,就是用来展示一组可以通过手势滑动的视图,用户可以随意向左或向右滑动。但总有些时候,我们会有一些比较奇怪的场景,这些场景下我们依然需要使用ViewPager,却需要它不能跟随手势进行切换。比如,我们做了一个模拟人机考试的App,也就是模拟的学生在电脑上考试的场景,只能用鼠标点击上一题或下一题来切换,而不可能通过触摸电脑显示器去切换。产品定位就是无限仿真人机考试,于是在手机App上也要求我们实现类似功能,用户不能通过滑动来切换题目,必须通过点击按钮切换。
而产品功能设计需要实现大量类似页面的管理,显然使用ViewPager+Fragment最方便,因为每个页面布局是一样的,仅有数据不同,而FragmentPagerAdapter又可以自动管理批量的Fragment,完全不需要我们手动去通过add、show等方法来管理——实际上遇到大量相同页面不同数据的情况下,ViewPager+Fragment是非常合理的选择。好吧,剩下的问题就是,如何禁止让ViewPager左右滑动。
去看一眼ViewPager的源码,其实跟预料的差不多,左右滑动这些事件,肯定是在onInterceptTouchEvent和onTouchEvent里处理的,毕竟这也算是Android的一个惯例了。ViewPager作为一个底层的ViewGroup,从更底层那里传递过来的Touch事件,肯定要被ViewPager这里处理再传递到其上层的各个View里的。正常情况下,左右滑动的事件,ViewPager自己直接消费掉(其实也不一定,毕竟ViewPager里可能包裹着同样可以左右滑动的View如RecyclerView或者HorizontalScrollView等),来进行左右滑动的展示。
想要禁止ViewPager的左右滑动,那么直接不让它处理相应的Touch事件就行了,很简单的就是直接在onInterceptTouchEvent与onTouchEvent方法里直接返回false,表示ViewPager不消费事件,也不拦截事件,相应的事件直接传递到更上层的View里进行处理——比如在文章开头提到的场景里,就是ViewPager直接把事件传递给Fragment里的View。
下面看一下这个非常简单的、改动后的ViewPager吧:
public class NoScrollViewPager extends ViewPager { public NoScrollViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public NoScrollViewPager(Context context) { super(context); } @Override public boolean onTouchEvent(MotionEvent arg0) { return false; } @Override public boolean onInterceptTouchEvent(MotionEvent arg0) { return false; }
评论