二、Widget、Element、RenderObject

1,512 阅读2分钟

一、Flutter 之图像绘制原理

三、Flutter UI 更新流程

四、build 流程分析

五、layout 流程分析

六、Paint 绘制(1)

七、Paint 绘制(2)

八、composite 流程分析

九、Flutter 小实践

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 树重新创建开销就比较大