Flutter 渲染机制

80 阅读2分钟

1. Flutter

Flutter 不同于 RN、Weex 等框架(是在原生SDK中做了一层抽象),Flutter 是自绘UI,和自己的事件传递机制,保证了UI的一致性;Flutter 内置了SKia 渲染引擎,来进行UI的渲染。

2. 渲染过程

创建组件 =》 布局(确定Frame)=》 绘制(可视化对象)=》 提交给GPU

3. 过程

3.1 创建组件
Container(
  color: Colors.blue,
  child: Row(
    chindren: [
      Image.network('https://www.test.com/100.png'),
      const Text('A'),
    ],
  ),
);

3.2 元素树

元素树 是 组件树 和 渲染树的一个中间层

abstract class StatelessWidget extends Widget {
  const StatelessWidget({ Key key }) : super(key: key);
  @override
  StatelessElement createElement() => StatelessElement(this);
  @protected
  Widget build(BuildContext context);
}

每个Widget 通过 createElement 对应一个Element

  • 组件树: 其实就是一些配置信息,和组件的上下级等关系
  • 元素树
    • ComponentElement: 根节点
    • RenderObjectElement: 是 RenderObject 中间过渡层,通过BuildContext 处理widget的位置 和 拿到context
    • 组件更改是会重新创建新的组件(比如Text('A') 更换成 Text('B')),组件是会马上创建,元素树在显示帧切换的时候会保持,就是说 元素帧会通过diff算法检查组件树更改,仅仅对更改的部分做重建操作

image.png

3.3 渲染树

通过Element 去进行布局 拿到size ,然后给GPU 显示在屏幕上;

  • RenderObject ,抽象了布局和绘制
  • RenderObject 来定义一些常见的子类 RenderImage (负责渲染图片的),RenderParagragh(负责渲染文本)
  • 大部分组件通过继承RenderBox来负责进行渲染的,一般的父级别提供布局约束(比如设置最大 最小宽度,或者直接设置宽度),子控件根据自身的元素来得到一个size ,并和父级的约束比较,拿到一个最终的size,并传给父级别;

image.png

RenderBox 提供一个约束,然后子控件得到了Frame 又会重新给到上级;