Flutter渲染原理学习

前言

​写Flutter已有好几个月的时间了,最开始总会有一点点不适应,但是写一段时间后还是觉得蛮顺手的,而且支持热更,不需要等整个项目编译,提升了不少效率。但是在开发过程中,总是会遇到因为Widget嵌套得不好而出现一些错误,于是一直想学习一下它的相关原理看看是为什么。所以通过学习和参考网上大神分享的的一些资料,整理出了今天要分享的文章。

正文

Flutter有三棵重要的树,分别是Widget树、Element树、RenderObject树,它们各司其职,分成了几个相关联但清晰的结构。Widget树与我们日常开发接触最多,其它的两棵树比较少接触到。
这三棵树的关联的大致流程:根据Widget生成Element,然后创建相应的RenderObject并关联到Element.renderObject属性上,再完成布局排列和绘制。最后合并层级,通过Skia引擎渲染为GPU数据,然后GPU接着将数据交给显示器显示。

它们三者的联系如下图:
在这里插入图片描述

如果最开始有人告诉你写Flutter就像在写配置,你会不会觉得不太可能。那么一起通过下面的内容看看这句话到底是不是真的。

Widget

Widget只是UI元素中的配置数据,并且一个Widget可以对应多个Element。真正的UI渲染树是由Element构成的。

日常开发中,常见结构如下图:
在这里插入图片描述

重要成员

  • Key:跟Widget的runtimeType一起决定此Widget是否复用
  • createElement方法:创建对应的Element
  • canUpdate方法:对比runtimeType和Key,相等的话表示就会用新的Widget去更新Element,否则的话会重新创建Element对象。
static bool canUpdate(Widget oldWidget, Widget newWidget) {
   
  return oldWidget.runtimeType == newWidget.runtimeType
      && oldWidget.key == newWidget.key;
}

StatelessWidget

  • 用于不需要维护状态的Widget
  • createElement方法返回的是StatelessElement对象

StatefulWdiget

  • createElement方法返回的是StatefulElement对象
  • createState方法返回一个State对象,维护状态信息

State

  • 在第一次插入到树中被创建,它的widget成员可能会被更新,在mount的时候,会调用firstBuild方法,firstBuild方法会调用rebuild方法
  • 调用setState方法后,会调用对应Element的markNeedsBuild:被标记为dirty,并且会调用owner.scheduleBuildFor(this),然后会触发rebuild。

Element

mount方法中调用Widget去创建一个RenderObject,创建的RenderObject会被Element持有;然后插入到渲染树中。(RenderObjectElement等等),代码如下:

void mount(Element parent, dynamic newSlot) {
   
  super.mount(parent, newSlot);
 
  _renderObject = widget.createRenderObject(this);
	//省略
  attachRenderObject(newSlot);
  _dirty = false;
}
  1. 创建一个RenderObject
  2. 加入到渲染树

当配置改变,Widget会根据runtimeType和Key去比较,判断是否可复用Elemen,可复用的话,则更新Element的配置,否则新建一个(Widget中的canUpdate方法决定)

rebuild方法会调用performRebuild方法

void performRebuild() {
   
 
  Widget built;
  try {
   
      built = build();
  } catch (e, stack) {
   
    
  } finally {
   
    // We delay marking the element as clean until after calling build() so
    // that attempts to markNeedsBuild() during build() will be ignored.
    _dirty = false;
  }
  try {
   
    _child = updateChild(_child
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值