CoordinatorLayout事件分析

首先明确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上


recyclerView事件分发
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()等方法,会方便处理事件。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容