【Android ViewPager】解決ViewPager巢狀時在API 13及其以下版本中不能滑動的問題

panpf發表於2019-04-15

通過對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)即可,如下:

這裡寫圖片描述

詳情可檢視我開源的專案ViewPagerCompat github.com/xiaopansky/…

相關文章