最后一步进行“光栅化”(Rasterize),前一步得到合成的视图数据其实还是一份矢量描述数据,光栅化帮助把这份数据真正地生成一个一个的像素填充数据。在 Flutter 中,光栅化这个步骤被放在了 Engine 层中。
在日常开发学习中,我们只需要在代码层配置好我们的 Widget 树,了解各种 Widget 特性及使用方法,其余的工作都可以交给我们的框架层去实现。
3 元素树详解
我们已经知道了各类控件的作用及其使用方法,这些 Widget 被我们开发人员配置了多个属性来定义它的展现形式,例如配置 Text 组件需要显示的字符串,配置输入框组件需要显示的内容。我们 Element 树会记录这些配置信息。熟悉 React 的读者可能了解过其中的 “虚拟 DOM” 这个概念,上述 Flutter 这种操作也正体现了这一概念。Widget 是不可变,它的改变就意味着要重建,而其重建也非常频繁,如果我们将更多的任务都交给它将会对性能造成很大的损伤,因此我们把 Widget 组件当作一个虚拟的组件树,而真正被渲染在屏幕上的其实是 Elememt 这棵树,它持有其对应 Widget 的引用,如果他对应的 Widget 发生改变,它就会被标记为 dirty Element,于是下一次更新视图时根据这个状态只更新被修改的内容,从而达到提升性能的效果。
每次,当控件挂载到控件树上时,Flutter 调用其 createElement() 方法,创建其对应的 Element。Flutter 再将这个 Element 放到元素树上,并持有创建它控件的引用,如下图:
控件会有它的子树:
子控件也会创建相应 Element 被放在元素树上:
4Element 中的状态
我们上文提到了 Widget 的不可变性,相应的 Element 就有其可变性,正如我们前文所说的它被标记为 dirty Element 便是作为需要更新的状态,另外一个我们需要格外注意的是,有状态组件(StatefulWidget)对应的 State 对象其实也被 Element 所管理ÿ