Nested滚动分析
存在的目的为了打破传统事件处理机制,允许ViewParent优先响应处理子View的触摸事件
传统事件处理流程
Google 大神 Dave Smith 在很多年前对Android整个touch事件的做了一个很全面的整理,可见 Matering Android’s Touch System,浓缩成简洁的图表示如下:
简单一句话描述就是触摸事件是从Parent -> Child的方向传递,由最上层的Child优先处理事件,如果不处理才会依次向下交由Parent处理
Nested机制后的事件处理流程
如上图所示,Nested滚动机制就是为了打破传统的事件分发机制,让Parent控件能优先接触并且处理消费触摸事件,最典型的应用就是 滚动吸附的效果
Nested机制流程
Nested机制能够让Parent View和Child View在滚动事件消费的过程中进行配合,基本流程如下:
当Child View开始滚动之前,可以通知Parent View,让其先于判断是否需要处理滚动;
Parent View不拦截,Child View则消费滚动;
Child View滚动之后,还可以通知父view继续滚动。
要实现这样的交互逻辑,首先Parent View要实现NestedScrollingParent接口,而Child View需要实现NestedScrollingChild接口,此机制中Child View是发起方,Parent View是接受回调处理方。
由于此机制是在5.0 Lollipop后提出的,因此在5.0系统上的原生View已经默认支持了Nested机制,并且在Support V7中做了支持。
实现流程
两接口
NestedScrollingChild
由Child View实现,NestedScrollingParent
由Parent View实现
两帮助类
NestedScrollingParentHelper
:主要是对应NestedScrollingParent
的接口的实现方法,具体代码可参见NestedScrollingChildHelper
: 主要对应NestedScrollChild接口的实现方法,具体代码可参见
目前大部分的View都对应实现了接口,如:
NestedScrollView
已经实现了NestedScrollingChild
和NestedScrollingParent
两个接口RecycleView
已经实现了NestedScrollingChild
CoordinatorLayout
实现了NestedScrollingParent
(Behavior机制就是根据此来实现的)
NestedScrollingChild
接口解释
具体实现参考NestedScrollingChildHelper,所有回调的核心实现通过此helper工具类实现与Parent回调交互
接口名 | 解释 |
---|---|
startNestedScroll | 检查此View的父类是否支持Nested, 如果支持则通过NestedScrollingChildHelper分别回调 onStartNestedScroll 和 onNestedScrollAccepted,代码逻辑参见 |
dispatchNestedPreScroll | ACTION_MOVE分发滚动事件时响应,代码逻辑参见 |
dispatchNestedScroll | ACTION_MOVE开始分发滚动事件,代码逻辑参见 |
stopNestedScroll | ACTION_UP触发时回调,代码逻辑参见 |
NestedScrollingParent
接口解释
忽略不赘述,具体与NestedScrollingChild和NestedScrollingChildHelper的交互逻辑类似
回调交互流程
注:下图忽略了一些Fling等一些非必要的回调
以下从 Child startNestedScroll回调触发到 Parent onStartNestedScroll回调分析下这个流程路径: