Flutter 渲染机制的核心是 Widget 树、Element 树、RenderObject 树的协同工作,三者共同实现高效UI更新:
🔗 三棵树关系图谱
graph LR
A[Widget树] -->|创建/更新| B[Element树]
B -->|持有引用| C[RenderObject树]
C -->|布局/渲染| D[屏幕像素]
🌳 三棵树的核心职责
树类型 | 生命周期 | 是否可变 | 主要职责 | 特点 |
---|---|---|---|---|
Widget树 | 短暂 | 不可变 | 描述UI的静态结构和配置信息 | 轻量级,build()时重建 |
Element树 | 持久 | 可变 | 管理Widget实例化和状态更新 | 复用元素优化性能 |
RenderObject树 | 持久 | 可变 | 执行布局、绘制、命中测试等底层渲染操作 | 实际控制屏幕显示 |
⚙️ 协作流程
-
构建阶段
- Widget 树通过
build()
声明 UI 结构(如Text()
、Container()
) - 每个 Widget 创建对应的 Element 实例(
createElement()
方法) - Element 生成关联的 RenderObject(
createRenderObject()
方法)
- Widget 树通过
-
更新阶段
- Widget 变更时,Element 通过
canUpdate()
对比新旧 Widget(检查 runtimeType 和 Key) - 可复用的 Element 更新关联 Widget,触发 RenderObject 重绘
- 不可复用则重建 Element 和 RenderObject
- Widget 变更时,Element 通过
-
渲染阶段
- RenderObject 计算布局(
layout()
)和绘制(paint()
) - 最终输出像素到屏幕
- RenderObject 计算布局(
💡 关键协作机制
- 复用优化:Element 树通过复用相同位置的 Element 避免重复创建 RenderObject
- 状态管理:StatefulWidget 的状态由 Element 持有,Widget 重建时状态保留
- 高效更新:RenderObject 仅对实际变化的 UI 部分重绘(VSYNC 信号驱动)
三棵树共同构成声明式UI的核心:Widget 描述"是什么",Element 管理"如何变",RenderObject 执行"怎么画"。