flutter的渲染流程

86 阅读2分钟

flutter 的三棵树

widget tree 和 renderobject tree 以及Element tree

widget tree 也就是我们使用的widget所组成的tree结构。

renderobject tree 是要渲染出来的树结构,并不是widget最终都会生成renderobject tree。

Element tree则是连接介于widget tree 和 renderobject tree 之间的结构,Element tree类似于虚拟dom的功能,它会根据widget tree的改变,然后根据diff算法进行改变,最终影响renderobject tree。

组件widget:不会生成renderobject

  1. Container();
  2. Text();
  3. ...

以Container 为例子,看下Container的继承关系和实现。可以看到它并没有和renderobject有直接的继承关系。

graph TD
Container继承 --> StatelessWidget继承 --> Widget

渲染widget:生成renderobject

  1. Padding();
  2. Row();
  3. ...

以Padding为例子,看一下它的继承关系和实现,它是继承了RenderObjectWidget抽象类,RenderObjectWidget类是有一个抽象方法: createRenderObject的,通过这个抽象方法实现创建RenderObject。 padding -> createRenderObject -> RenderPadding -> RenderBox -> RenderObject。

graph TD
Padding继承 --> SingleChildRenderObjectWidget继承 --> RenderObjectWidget继承 --> Widget

Element Tree

通过上面的介绍可以看到,所有的widget 都会继承Widget()这个类,这个类中有一个抽象方法createElement(),用于创建Element。这也就是说所有的widget都会创建一个Element,不同的widget创建的Element会有所不同,例如在StatelessWidget 中会创建一个StatelessElement()。Element 也可以分为:

  1. RenderObjectElement:mount方法-> _widget.createRenderObject

  2. ComponentElement:mount方法-> _firstBuild -> rebuild -> performRebuild -> build -> _widget_build。这就说明 ComponentElement 更多的是为了执行build方法,这里的build方法,也就是我们在widget中写的build方法,

1681805366470.png

StatefulElement 也是继承自 ComponentElement,但是在StatefulElement的构造方法中,调用了_state = widget.createState(), 来创建widget的state, state._widget = widget,这样就可以在state中使用widget字段获取StatefulWidget的变量。

1681807894217.png

class Bird extends StatefulWidget { 
  const Bird({ super.key, this.color = const Color(0xFFFFE306), this.child, }); 
  final Color color; 
  final Widget? child;
  @override State<Bird> createState() => _BirdState(); 
}

class _BirdState extends State<Bird> { 
  double _size = 1.0; 
  void grow() { setState(() { _size += 0.1; }); } 
  
  @override Widget build(BuildContext context) { 
    return Container( 
      color: widget.color, // 使用widget.color
      transform: Matrix4.diagonal3Values(_size, _size, 1.0), 
      child: widget.child, ); 
    }
  }

总价

通过对这的了解,简单看一下它们之间的关系,明确flutter的渲染流程。