此篇文章需要用到之前的知识点,即我之前写的这两篇博客
事件分发机制原理分析
NestedScrolling机制原理分析
一.CoordinatorLayout基本介绍
1.使用场景
一般作为应用的顶层布局,同时也作为一个管理容器,管理与子view 或者 子view之间的交互。那么都具体管理啥呢?可以分成四个部分
2.作用
- ①处理子控件之间依赖下的交互
- ②处理子控件之间的嵌套滑动
- ③处理子控件的测量与布局
- ④处理子控件的事件拦截与响应
以上四个功能,都建立于CoordainatorLayout中提供的一个叫做Behavior的**“ 插件”**之上。Behavior内部也提供了相应方法来对应这四个不同的功能。那么都有哪些方法呢?
3.Behavior中的常用方法

4.为什么把这些方法都放到Behavior中呢?
答案:解耦。当用的时候就集成进去,不用的时候就remove。即可插拔。
- 在这里可以把
CoordinatorLayout比喻成Android Studio,把子View比喻成我们的项目。我们知道,AS可以使用Plugins为项目引入各种插件,从而实现不同的功能,同样的道理,CoordinatorLayout可以使用Behavior为子View引入各种行为。Behavior也是**“可插拔”**
二.CoordinatorLayout四个功能的原理
1.CoordinatorLayout下依赖交互功能原理(观察者模式)
当CoordainatorLayout中子控件depandency的位置、大小等发生改变的时候,那么在CoordainatorLayout内部会通知所有依赖depandency的控件,并调用对应声明的Behavior,告知其依赖的depandency发生改变。
- 那么如何判断依赖是哪个
View呢?
layoutDependsOn方法 - 接受到通知后如何处理呢?
onDependentViewChanged/onDependentViewRemoved方法
原理图

dependency也是一个child,和child1、child2在布局上可以是并列的。后面我们把dependency统一称为DepandedView
2.CoordinatorLayout内部嵌套滑动原理
CoordinatorLayout实现了NestedScrollingParent2接口。所以当事件(scroll或fling)产生后,内部实现了NestedScrollingChild接口的子控件会将事件传递给CoordinatorLayout,CoordinatorLayout又会将事件传递给所有的Behavior。然后在Behavior中实现子控件的嵌套滑动。

具体流程图

相对于NestedScrolling机制(参与角色只有子控件和父控件),CoordainatorLayout中的交互角色玩出了新高度,在CoordainatorLayout下的子控件可以与多个兄弟控件进行交互。即从1:1变成了1:N
3.CoordinatorLayout子控件的测量与布局
在特殊的情况下,如子控件需要处理宽高和布局的时候,那么交由Behavior内部的onMeasureChild与onLayoutChild方法来进行处理

4.CoordinatorLayout子控件的事件拦截与响应
对于事件的拦截与处理,如果子控件需要拦截并消耗事件,那么交由给Behavior内部的onInterceptTouchEvent与onTouchEvent方法进行处理

三.源码分析CoordinatorLayout子控件依赖交互功能原理
由于View的生命周期的开始是在onAttachedToWindow方法中,所以我们进入此方法寻找
1.我们在CoordinatorLayout类中找到onAttachedToWindow方法
发现它调用getViewTreeObserver,获得ViewTreeObserver,然后调用了addOnPreDrawListener

- 关于
ViewTreeObserver:
ViewTreeObserver注册一个观察者来监听视图树,当视图树的布局、视图树的焦点、视图树将要绘制、视图树滚动等发生改变时,ViewTreeObserver都会收到通知,ViewTreeObserver不能被实例化,可以调用View.getViewTreeObserver()来获得 - 关于
dispatchOnPreDraw:通知观察者绘制即将开始,如果其中的某个观察者返回true,那么绘制将会取消,并且重新安排绘制,如果想在View Layout或Viewhierarchy还未依附到Window时,或者在View处于GONE状态时强制绘制,可以手动调用这个方法
2.接下来我们看一下它添加的监听者是个啥,追踪addOnPreDrawListener,找到OnPreDrawListener类

当View发生变化的时候会调用onChildViewsChanged方法。
3.我们追踪onChildViewsChanged
它有一个类型,即type

也就是DispatchChangeEvent注解。我们点进去看一下

一个代表绘制之前,一个代表嵌套滑动,一个代表View移除。意思是说这三种类型的事件发生的时候会调用onChildViewsChanged方法。
我们深究一下这个方法
final void onChildViewsChanged(@DispatchChangeEvent final int type) {
。。。
//--------------------------------------
//--------------------------------------

本文深入剖析了Android CoordinatorLayout的工作原理,包括它的使用场景、作用,特别是Behavior中的方法以及如何实现子控件间的依赖交互、嵌套滑动、测量布局和事件处理。通过源码分析,揭示了CoordinatorLayout如何通过ObserverPattern实现子控件间的通信,以及事件传递机制。
最低0.47元/天 解锁文章
2632

被折叠的 条评论
为什么被折叠?



