iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 6
0
Mobile Development

Why Flutter why? 從表層到底層,從如何到為何。系列 第 6

days[5] = "三顆渲染樹是如何運作的?(二)"

上次我們從RichText出發,一步步摸索出了Widget, Element, RenderObject各自的責任,和彼此之間的相互關係。我們也看到RichText有這樣的繼承關係:

class RichText extends MultiChildRenderObjectWidget
abstract class MultiChildRenderObjectWidget extends RenderObjectWidget

MultiChildRenderObjectWidget產生的MultiChildRenderObjectElement則是這樣的關係:

class MultiChildRenderObjectElement extends RenderObjectElement
abstract class RenderObjectElement extends Element

最後RichText產生的RenderParagraph則是:

class RenderParagraph extends RenderBox
abstract class RenderBox extends RenderObject

光是一個簡單的RichText就牽涉到這麼多的class,它們彼此之間到底是如何對應的?而我們平常在使用的眾多Widget,它們對應的ElementRenderObject又是什麼?讓我們來看看:
https://ithelp.ithome.com.tw/upload/images/20200906/20129053r4L3PiWuZw.png
這裡我們畫出了Widget, Element, RenderObject各自的繼承關係圖,以及它們之間的(顏色)對應關係。我們可以看到,WidgetElement之間有著明顯的一對一的關係,StatelessWidget產生StatelessElementSingleChildRenderObjectWidget產生SIngleChildRenderObjectElement...等等。

然而,RenderObject卻沒有和WidgetElement對應的架構。RenderObjectWidget底下的PaddingRichTextRawImage,分別建立了RenderObject這邊的RenderPaddingRenderParagraphRenderImage,而StatelessWidgetStatefulWidget這邊,我們常見的各種Widget卻沒有對應的RenderObject

顯然,只有RenderObjectElement才會呼叫RenderObjectWidget去產生RenderObject,而ComponentElement(StatelessElement&StatefulElement並不會呼叫StatelessWidgetStatefulWidget去產生RenderObject,畢竟這兩種Widget本身是由其它Widget複合而成的,不會建立自己的RenderObject

簡單來說,既然整個Widget Tree是一個由各種Widget複合出來的樹,我們要去渲染它時自然會遞迴地去呼叫StatelessWidgetStatefulWidgetbuild函數,直到我們遇到某個沒有build函數的RenderObjectWidget,就由它產生其對應的RenderObject

最後我們以這個簡單的APP為例:

void main() {
  runApp(Container(
    alignment: Alignment.center,
    child: Text(
      'Hello, World!',
      textDirection: TextDirection.ltr,
    ),
  ));
}

我們可以得到這樣的三顆渲染樹:
https://ithelp.ithome.com.tw/upload/images/20200906/20129053oOIcCkKOu3.png
注意到雖然我們只複合了ContainerText兩個Widget,但當我們在Container上設置各種參數(如alignment)時,它的作用其實是幫我們在我們傳入的child(Text)之上,再去複合各種Widget。最終的四層Widget Tree,產生了對應的四層Element Tree,但只有在遇到RenderObjectWidget時才會去產生RenderObject


雖然一直逃避作圖到現在,但老實說網路上每一篇關於Flutter渲染樹的文章幾乎都有精美的示意圖,只有我不畫好像有點說不過去。因為美術細胞趨近於零所以又花了不少時間,下次我們終於可以進入真正有趣的部份了:渲染樹的生命週期,也就是從APP啟動,渲染樹建立、更新到回收的整個流程細節,敬請期待!(不保證是下一篇)


上一篇
days[4] = "三顆渲染樹是如何運作的?"
下一篇
days[6] = "三顆渲染樹是如何運作的?(三)"
系列文
Why Flutter why? 從表層到底層,從如何到為何。30

尚未有邦友留言

立即登入留言