1. 前言:从 Compose 生命周期说起

Compose 绘制生命周期为三个阶段:
- Composition/组合:Composable 源码经过运行后生成
LayoutNode的节点树,这棵树被称为 Composition。 - Layout/布局:对节点树深度遍历测量子节点的尺寸,并将其在父容器内摆放到合适的位置。
- Drawing/绘制:基于布局后拿到的尺寸和位置信息,绘制上屏。
我们与 Android 经典视图系统的生命周期(Measure,Layout,Drawing)做一个对比:组合是 Compose 的特有阶段,是其能够通过函数调用实现声明式 UI 的核心,想要深入理解 Compose 第一课就是理解这个过程。但我已经有一些文章介绍过了,不在本文讨论范围。可以参考 深入理解 Jetpack Compose 内核:SlotTable 系统
绘制阶段与传统视图大同小异,都是通过 Android Cavas API ,底层调用 skia 实现,本文也不做讨论。
本文讨论的重点是布局阶段。Compose 的布局把 Measure 也了囊括进来,相对于 Android View 有相似性,但也有其独有的特点和优势,接下来我们进入正题。
2. Compose 布局过程三步走
Compose 布局包括三个阶段,从当前 Node 出发,需要依次经历:
- Measure children: 深度遍历子节点,并测量它们的尺寸。
- Decide own size:根据收集到的子节点尺寸,决定当前节点自己的尺寸
- Place children:将子节点摆放到合理的相对位置

上面代码描述了一个卡片的布局,下面以这个布局的节点树为例,看一下布局流程

- Step1:从
Row开始发起测量,遵循三步走第一步,深度遍历测量其子节点Image和Column - Step2&3:
Image发起测量,因为没有子节点需要测量了,所以只需要计算自己的尺寸,也因为没有子节点需要摆放,空实现完成 place 即可。 - Step4:
Column发起测量,因其有子节点,继续深度遍历 - Step5&6:测量 Text ,因为一个叶子节点,立即完成自己的 Size 和 Place 阶段
- Step7&8:测量另一个 Text,同上
- Step9:Column 拿到两个子 Text 返回的 Size 后,计算出自己的 Size,不难猜到其计算逻辑应该是 width = maxOf(child1.w, child2.w), height = sumOf(child1.h, child2.h)。 设置自己的 width 和 height 后,对两个子 Text 进行 Place, 垂直线性摆放。
看一下代码是如何实现这三步。
所有的 Composable 最终都会调用一个公共 Layout Composable 方法,这里面创建 LayoutNode 存储在 Composition 节点树

以 Column 的实现为例,可以看到调用 Layout 时,传入了三个参数
- content:在这里定义子 Composable ,组合过后形成当前节点的子节点
- measurePolicy:这是定义了布局的三步走核心逻辑
- modifier:修饰符链,参与到布局或者绘制阶段
measurePolicy和 modifier 会存储在当前 LayoutNode 上,等待 measure 的开始参与其中。下面重点分析 MeasurePolicy 了解三步走如何实现。

最低0.47元/天 解锁文章
713

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



