这是我参与11月更文应战的第27天,活动详情检查:2021最后一次更文应战

1. 烘托原理

Flutter实战中写道,Flutter 框架的布局、制作的处理流程是这样的:

  • 依据 Widget 树生成一个 Element 树,Element 树中的节点都承继自 Element 类。
  • 依据 Element 树生成 Render 树(烘托树),烘托树中的节点都承继自RenderObject 类。
  • 依据烘托树生成 Layer 树,然后上屏显现,Layer 树中的节点都承继自 Layer 类。 真正的布局和烘托逻辑在 Render 树中,Element 是 Widget 和 RenderObject 的粘合剂,能够理解为一个中间署理。

2. Render 树

不是一切的Widget 都会生成render,比方Container就不会创立RenderObject。

Flutter —— 渲染原理

只要承继自RenderObject类的目标才会生成RenderObject目标,比方Column,这样就会被烘托引擎直接烘托。

在renderObject里边有两个重要的办法便是createElement 和 createRenderObject,这两个办法都是抽象办法,那么在子类中应该有相应的完成。

Flutter —— 渲染原理

先来看createRenderObject办法,在flex中找到了createRenderObject的完成。createRenderObject里边仅仅做了一件事便是创立了RenderFlex

Flutter —— 渲染原理

点进去看到RenderFlex承继自RenderBox。

Flutter —— 渲染原理

在点进去看到RenderBox承继自RenderObject。

所以createRenderObject也便是回来了一个RenderObject目标。那么也便是说,并不是一切的Widget都会独立烘托,只要完成了createRenderObject而且回来了RenderObject目标的才会被独立烘托。

3. Element 树

一切的Widget都会创立一个Element目标。看到之前的createElement办法。

  RenderObjectElement createElement();

看一下子类是如何完成createElement办法的。这儿在MultiChildRenderObjectWidget找到了办法的完成,这儿回来了一个MultiChildRenderObjectElement目标。

Flutter —— 渲染原理

MultiChildRenderObjectElement承继自RenderObjectElement。

接下来看StatelessWidget 里边是否有完成createElement办法。进去后发现是有的。

Flutter —— 渲染原理

再来看一下StatefulWidget,也是有的。

Flutter —— 渲染原理

而这儿也能够看到,一切承继自Widget的,都有element。所以这儿能够得知,Widget树和element树是一一对应的联系。

Flutter —— 渲染原理

在StatefulWidget里边的createElement打下断点后运行。

Flutter —— 渲染原理

这儿第一个调用这个办法的是material app。

Flutter —— 渲染原理

如果是StatelessWidget里边的createElement的话那么就应该是MyApp。

Flutter —— 渲染原理

往下走一步之后来到了这儿,看到有调用一个mount办法。

Flutter —— 渲染原理

点进去之后看到注释,大概便是说当有一个新的element被增加的时分,mount办法都会被调用一次。也便是说当有一个新的Widget被创立的时分,mount办法都会被调用一次。

Flutter —— 渲染原理

接下来看renderObject里边的mount办法。 在MultiChildRenderObjectWidget里边的createElement办法打下断点。

Flutter —— 渲染原理

点击下一步发现也是有调用mount办法的。

Flutter —— 渲染原理

而createRenderObject在mount办法之后也便是createElement办法之后。所以过程是Widget树 —— Element树 —— Render树

Flutter —— 渲染原理

在createRenderObject下面一个函数mount里边就会调用createRenderObject创立RenderObject。

Flutter —— 渲染原理

4. Element 和 Widget 的联系

StatelessWidget中createElement的是StatelessElement。

Flutter —— 渲染原理

StatelessElement 承继自ComponentElement

Flutter —— 渲染原理

来到ComponentElement,看到了这儿有mount办法,在mount里边调用了_firstBuild办法。

Flutter —— 渲染原理

_firstBuild里边则调用了rebuild。

Flutter —— 渲染原理

rebuild里边也有一堆判断,然后调用了performRebuild办法。

Flutter —— 渲染原理

看到performRebuild仅仅一个界说。

Flutter —— 渲染原理

接下来去componentElement里边看performRebuild办法。看到这儿有个built变量,而且等于build办法

Flutter —— 渲染原理

看到build仍是一个办法的界说。

Flutter —— 渲染原理

看到StatelessElement里边的build办法直接回来widget的build办法的回来值,而这个widget便是StatelessWidget。

Flutter —— 渲染原理

那么也便是说,当创立一个StatelessWidget目标的时分,就会

  • 调用createElement办法,
    • 创立componentElement目标,调用mount办法
  • 调用_firstBuild办法
  • 调用rebuild办法
  • 调用performRebuild办法
  • 调用了StatelessElement里边的build办法
  • 调用了StatelessWidget目标的build办法进行烘托

这儿证明StatelessElement里边的widget是外面的StatelessWidget目标。 当这儿调用createElement的时分,这儿的this便是StatelessWidget目标。

Flutter —— 渲染原理

而在StatelessElement时分,这儿边的widget便是传进来的StatelessWidget目标,而且传给了super。

Flutter —— 渲染原理

来到ComponentElement,又传给了ComponentElement的super。

Flutter —— 渲染原理

然后看到Element里边接纳到了这个widget,就赋值给了_widget。

Flutter —— 渲染原理

  • Widget的烘托原理
    • 并不是一切的Widget都会被独立烘托!只要承继RenderObjectWidget的才会创立RenderObject目标!
    • 在Flutter烘托的流程中,有三颗重要的树!Flutter引擎是针对Render树进行烘托!
      • Widget树、Element树、Render树
        • 每一个Widget都会创立一个Element目标
          • 隐式调用createElement办法。Element加入Element树中,它会创立三种Element
          • RenderElement首要是创立RenderObject目标, 承继RenderObjectWidget的Widget会创立RenderElement
            • 创立RanderElement
            • Flutter会调用mount办法,调用createRanderObject办法
          • StatefulElement承继ComponentElement,StatefulWidget会创立StatefulElement
            • 调用createState办法,创立State
            • 将Widget赋值给state
            • 调用state的build办法 而且将自己(Element)传出去,build里面的context 便是Widget的Element !
          • StatelessElement承继ComponentElement,StatelessWidget会创立StatelessElement
            • 首要便是调用build办法 而且将自己(Element)传出去