Material Design之CoordinatorLayout原理剖析

此篇文章需要用到之前的知识点,即我之前写的这两篇博客
事件分发机制原理分析
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,和child1child2在布局上可以是并列的。后面我们把dependency统一称为DepandedView

2.CoordinatorLayout内部嵌套滑动原理

CoordinatorLayout实现了NestedScrollingParent2接口。所以当事件(scrollfling)产生后,内部实现了NestedScrollingChild接口的子控件会将事件传递给CoordinatorLayoutCoordinatorLayout又会将事件传递给所有的Behavior。然后在Behavior中实现子控件的嵌套滑动。
在这里插入图片描述
具体流程图
在这里插入图片描述

相对于NestedScrolling机制(参与角色只有子控件和父控件),CoordainatorLayout中的交互角色玩出了新高度,在CoordainatorLayout下的子控件可以与多个兄弟控件进行交互。即从1:1变成了1:N

3.CoordinatorLayout子控件的测量与布局

在特殊的情况下,如子控件需要处理宽高和布局的时候,那么交由Behavior内部的onMeasureChildonLayoutChild方法来进行处理
在这里插入图片描述

4.CoordinatorLayout子控件的事件拦截与响应

对于事件的拦截与处理,如果子控件需要拦截并消耗事件,那么交由给Behavior内部的onInterceptTouchEventonTouchEvent方法进行处理
在这里插入图片描述

三.源码分析CoordinatorLayout子控件依赖交互功能原理

由于View的生命周期的开始是在onAttachedToWindow方法中,所以我们进入此方法寻找

1.我们在CoordinatorLayout类中找到onAttachedToWindow方法

发现它调用getViewTreeObserver,获得ViewTreeObserver,然后调用了addOnPreDrawListener
在这里插入图片描述

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

在这里插入图片描述
View发生变化的时候会调用onChildViewsChanged方法。

3.我们追踪onChildViewsChanged

它有一个类型,即type
在这里插入图片描述
也就是DispatchChangeEvent注解。我们点进去看

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值