首先明确AppbarLayout默认的Behavior是 AppbarLayout.Behavior
RecyclerView的Behavior为AppbarLayout.ScrollingViewBehavior
触摸在AppbarLayout上面
1 : 触摸在AppBarLayout上面, 首先CoordinatorLayout接收事件,走onInterceptTouchEvent(), 然后先去判断behavior是否拦截事件,return 结果。
2 : 事件继续向下传递,因为AppbarLayout没有重写dispatchEvent() onInterceptTouchevent(),onTouchEvent()方法,默认走viewGroup的分发方法,默认不拦截。
3 :最终回到AppbarLayout的onTouchEvent()方法,和之前一样,先调用behavior的OnTouchEvent()方法,
返回true,则该事件在CoordinatorLayout的OntouchEvent()中处理,之后move事件不再走onInterceptTouchEvent() AppBarLayout开始滚动。
4 : OnPreDrawListener 监听View树的改变,因此onChildViewsChanged() 被调用,之后双层for循环,遍历每个控件和其他控件是否有依赖关系。调用behavior的b.onDependentViewChanged(this,checkChild,child); 然后ScrollingViewBehavior就被调用,recyclerView调用offsetChildAsNeeded()方法开始滚动。
触摸再RecyclerView上
1 触摸在recyclerView上面。首先CoordinatorLayout接收事件,走onInterceptTouchEvent(), 然后先去判断behavior是否拦截事件,return 结果。
2 : 返回false不拦截,直接传递给recyclerview的onInterceptTouchEvent(),返回false ,不拦截,接着传递。
3 : 传递到OnTouchEvent方法上面,return true,之后move事件,recyclerView的move事件不会再经由recyclerView的onInterceptTouchEvent() 直接较给recyclerView的onTouchEvent()方法处理了。
4 : recyclerView的OntouchEvent()方法中,调用onNestedpreScroll() 判断AppBarLayout是否消费距离。如果消费了,recylerview减去距离后,调用内部滚动。
总结
AppbarLayout上面,RecyclerView是通过RecyclerView的behavior改变onDependentViewChanged滚动的。
RecyclerView上面,AppBarLayout是通过AppbarLayout的behavior的onNestedPreScroll() ,onNestedScroll()
可以理解为:
触摸非滚动View上,其他的view使用依赖关系,被动依赖。
触摸在滚动View上,其他View使用监听滚动onNestedPreScroll(),onNestedScroll(),主动有反馈。
当然View可以任意组合,但原生的recyclerView都提供了onNestedPreScroll()等方法,会方便处理事件。