作用
Android的事件分發(fā)機制無法實現(xiàn)流暢嵌套滑動,因為當(dāng)子控件消費了事件, 那么父控件就不會再有機會處理這個事件了阶剑。
嵌套滑動的相關(guān)邏輯作為普通方法直接寫進了最新的(SDK21之后)View和ViewGroup類虹蓄。而SDK21之前的版本,官方在android.support.v4兼容包中提供了兩個接口NestedScrollingChild和NestedScrollingParent, 還有兩個輔助類NestedScrollingChildHelper和NestedScrollingParentHelper來幫助控件實現(xiàn)嵌套滑動.
基本原理
嵌套滑動的基本原理是在子控件接收到滑動一段距離的請求時, 先詢問父控件是否要滑動, 如果滑動了父控件就通知子控件它消耗了一部分滑動距離, 子控件就只處理剩下的滑動距離, 然后子控件滑動完畢后再把剩余的滑動距離傳給父控件.
通過這樣的嵌套滑動機制, 在一次滑動操作過程中
父控件和子控件都有機會對滑動操作作出響應(yīng), 尤其父控件能夠分別在子控件處理滑動距離之前和之后對滑動距離進行響應(yīng).
這解決了事件分發(fā)機制缺點引起的問題.
NestedScrollingChild
startNestedScroll : 起始方法, 主要作用是找到接收滑動距離信息的外控件.
dispatchNestedPreScroll : 在內(nèi)控件處理滑動前把滑動信息分發(fā)給外控件.
dispatchNestedScroll : 在內(nèi)控件處理完滑動后把剩下的滑動距離信息分發(fā)給外控件.
stopNestedScroll : 結(jié)束方法, 主要作用就是清空嵌套滑動的相關(guān)狀態(tài)
setNestedScrollingEnabled和isNestedScrollingEnabled : 一對get&set方法, 用來判斷控件是否支持嵌套滑動.
dispatchNestedPreFling和dispatchNestedFling : 跟Scroll的對應(yīng)方法作用類似, 不過分發(fā)的不是滑動信息而是Fling信息.(這個Fling好難翻譯.. =。=)本文主要關(guān)注滑動的處理, 所以后續(xù)不分析這兩個方法.
從方法名就可以看出
內(nèi)控件是嵌套滑動的發(fā)起者.
NestedScrollingParent
因為內(nèi)控件是發(fā)起者, 所以外控件的大部分方法都是被內(nèi)控件的對應(yīng)方法回調(diào)的.
onStartNestedScroll : 對應(yīng)startNestedScroll, 內(nèi)控件通過調(diào)用外控件的這個方法來確定外控件是否接收滑動信息.
onNestedScrollAccepted : 當(dāng)外控件確定接收滑動信息后該方法被回調(diào), 可以讓外控件針對嵌套滑動做一些前期工作.
onNestedPreScroll : 關(guān)鍵方法, 接收內(nèi)控件處理滑動前的滑動距離信息, 在這里外控件可以優(yōu)先響應(yīng)滑動操作, 消耗部分或者全部滑動距離.
onNestedScroll : 關(guān)鍵方法, 接收內(nèi)控件處理完滑動后的滑動距離信息, 在這里外控件可以選擇是否處理剩余的滑動距離.
onStopNestedScroll : 對應(yīng)stopNestedScroll, 用來做一些收尾工作.
getNestedScrollAxes : 返回嵌套滑動的方向, 區(qū)分橫向滑動和豎向滑動, 作用不大
onNestedPreFling和onNestedFling : 同上略
外控件通過onNestedPreScroll和onNestedScroll來接收內(nèi)控件響應(yīng)滑動前后的滑動距離信息.
再次指出, 這兩個方法是實現(xiàn)嵌套滑動效果的關(guān)鍵方法.