1、基本介绍
第一章提到,在 Flutter 的 Engine 层向 Dart 层的暴露了 Canvas, PictureRecorder 等接口,利用这些接口可以绘制自己想要的图像。通过直接调用 API 绘制图像,这种更像指令式操作。在 Flutter 中,可以以声明式组件构建自己的UI, 通过构建一个个的 Widget 组件,来声明界面应该有哪些功能,长什么样, 像 ReactNative 的虚拟 DOM 一样,这些 widget 并不是最终显示在 界面的组件。一个 Widget 构建 到最终显示在显示器上图像主要经历了三个阶段: Widget --> Element --> RenderObject
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Text('文本1'),
Row(
children: <Widget>[
Image.asset('/assets/images/test.png'),
Text('文本2')
],
)
],
);
}
在上面这个例子中,Widget 树有四个 widgets,两个 Row widget 及其子 widget。
在上示例子中,当要更新第二个Text的文本颜色时,销毁整个旧 WidgetTree,生成一棵新 WidgetTree,而ElementTree 与 RenderObjecrTree 只替换变更的节点。
2、三颗树职责
(1)Widget
UI 视图的配置信息,在 Flutter中,并不是通过指令的方式直接操作UI, 而是通过数据驱动驱动视图改变~ widget 描述了前配置和状态描述了它们的视图, 是不可变的,当某个widget的状态发生更改时,widget会重新构建所描述的视图。
widget 生成对应的渲染对象 renderObject 主要是通过 createRenderObject 方法,但是 并非所有的widget都能调用 createRenderObject 创建对应的 renderObject, 只有 RenderObjectWidget 类的widget 才拥有 createRenderObject 方法,那其他 StatelessWidget, StatefulWidget 这些,它们的 renderObject 是怎么来的呢?这个后面再分析
(2)RenderObject RenderObject的主要职责是,计算节点的大小,位置,进行相关绘制和布局操作,即最终真正的渲染对象
(3) Element widget 和 renderObject 的中间调度者
3、为什么需要三颗树?
widget 是比较轻量的,只是涉及相关UI 的配置信息,销毁重建成本比较低,但是 renderObject 涉及到 布局,绘制等复杂的操作,同时还包含对应的layer,是一个真正渲染的view,整个view 树重新创建开销就比较大