通过对ViewPager事件处理的分析发现解决此问题的关键点在于判断是否可以横向滑动的部分,也就是canScroll(View, boolean, int, int, int)方法
在此方法中先依次递归判断子View是否可以横向滑动,在最后一行则判断自己是否可以横向滑动。关键处在于调用了ViewCompat.canScrollHorizontally(View, int)方法来判断是否可以横向滑动。进一步查看ViewCompat.canScrollHorizontally(View, int)的源码
不同版本有不同的实现
ICS版本重写了canScrollHorizontally(View, int),调用ViewCompatICS.canScrollHorizontally(View, int)
ViewCompatICS.canScrollHorizontally(View, int)调用了View新增的canScrollHorizontally(int)方法
HCViewCompatImpl继承自GBViewCompatImpl,没有重写canScrollHorizontally(View, int)方法
GBViewCompatImpl继承自EclairMr1ViewCompatImpl,没有重写canScrollHorizontally(View, int)方法
EclairMr1ViewCompatImpl继承自BaseViewCompatImpl,没有重写canScrollHorizontally(View, int)方法
BaseViewCompatImpl的canScrollHorizontally(View, int)方法直接返回false
以上源码分析可总结为在API14以上是调用View新增的canScrollHorizontally(int)方法判断的,而在API13及其以下则直接返回false,可以理解为不支持。
那么这就无解了吗,当然不能够。既然ViewPager在API14以上可以正常滑动那么必然是重写了canScrollHorizontally(int)方法,查看ViewPager的canScrollHorizontally(int)方法源码发现此方法不存在版本兼容问题,在API13及其以下版本上也可直接调用。于是乎解决办法就是继承ViewPager重写canScroll(View, boolean, int, int, int)方法,直接调用canScrollHorizontally(int)即可,如下:
详情可查看我开源的项目CompatViewPager https://github.com/xiaopansky/CompatViewPager