要做一個功能,使用Design Support Library的滑動折疊。滑動下方縱向的RecyclerView,折疊上方的圖片。同時,縱向RecyclerView嵌套一個橫向RecyclerView,支持左右滑動數字。
參考官方demo,很容易使用CoordinatorLayout和CollapsingToolbarLayout實現。添加縱向RecyclerView的時候,一切正常,但接著添加橫向RecyclerView時,滑動明顯出bug,上方的圖片無法自動折疊。
非橫向RecyclerView的區域可以正常觸發折疊,容易確定是橫向RecyclerView的事件沒有傳遞到CollapsingToolbarLayout。縱向RecyclerView已經設定了app:layout_behavior,內部的所有view都可以正常觸發折疊,橫向的RecyclerView理應也可以。
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild
查看RecyclerView的implements,NestedScrollingChild引起了我的注意,明顯寫著“嵌套”嘛。Android新引入NestedScrollView代替ScrollView,應該是為了解決滑動下嵌套的問題。
請教Google大神,最終為橫向RecyclerView增加一句setNestedScrollingEnabled(false),問題解決。
具體的代碼看CollapsingToolbarLayoutActivity
,一個我用來驗證代碼的工程,里面亂七八糟的。
在事件分發模型中,手指down、move、up整個滑動過程,一旦有View決定攔截這個事件,那么整個事件過程都交由它來處理,其他View沒有機會再處理了。
新的嵌套滑動機制增加支持子View和父View共同處理滑動事件的能力,子View處理事件的時候,能通知父View同時處理。
CoordinatorLayout實現了NestedScrollingParent,縱向RecyclerView是CoordinatorLayout的子View,RecyclerView的滑動能通知到CoordinatorLayout,繼而由CoordinatorLayout協調讓CollapsingToolbarLayout發生折疊。
上面出bug的原因也能理解了,橫向RecyclerView的父View是縱向RecyclerView,而RecyclerView只實現了NestedScrollingChild,無法像CoordinatorLayout一樣響應。所以要關閉橫向RecyclerView的嵌套滑動功能,讓橫向RecyclerView如同其他嵌入縱向RecyclerView的view一樣,觸發折疊。
本文主要是講解決bug的過程,知其然知其所以然,很有必要了解源碼實現。Android工程師必須熟練掌握View的事件體系,下次要歸納總結。