官术网_书友最值得收藏!

1.5 原理淺析——3棵重要的樹

在學(xué)習(xí)Flutter前,作為理論基礎(chǔ),我們還需要理解一些會(huì)經(jīng)常提及的概念,本節(jié)就揭秘Flutter框架層中最核心的概念。了解HTML的讀者一定聽說過“DOM樹”這個(gè)概念,它由頁面中一個(gè)個(gè)的標(biāo)簽構(gòu)成,這些標(biāo)簽所形成的一種天然的嵌套關(guān)系使它們可以表示為“樹”狀結(jié)構(gòu)。例如,下面這一段HTML代碼就可以使用圖1.15所示的HTML DOM樹的結(jié)構(gòu)來表示。

圖1.15 HTML DOM樹的結(jié)構(gòu)

<html>
  <body>
    <h1>...</h1>
    <p>...</p>
    <div>
      <a>...</a>
      <p>...</p>
    </div>
  </body>
</html>

Flutter中雖然沒有HTML、XML這類配置語言,但DOM樹同樣可以應(yīng)用在Flutter中。例如,在計(jì)數(shù)器應(yīng)用中很多組件可以通過child屬性設(shè)置它們的子組件,因此我們可以用一棵樹(見圖1.16)來表示計(jì)數(shù)器應(yīng)用的整體結(jié)構(gòu)。

圖1.16 計(jì)數(shù)器應(yīng)用的組件樹

和HTML中的標(biāo)簽不同,F(xiàn)lutter中的這棵樹由一個(gè)個(gè)組件組成,因此我們可以也將它稱為組件樹(widget tree),它就表示在Dart代碼中所寫的一個(gè)個(gè)組件所組成的結(jié)構(gòu)。然而,前面提到,應(yīng)用運(yùn)行后,組件渲染的任務(wù)并不在組件層完成,而在渲染層完成,從這里我們可以簡單地推斷出一個(gè)結(jié)論,這棵組件樹并不是真正意義上展示在手機(jī)屏幕上的各個(gè)組件。

Flutter官方文檔中組件的定義是不可變的UI描述信息。這意味著組件在創(chuàng)建后將不能再改變,當(dāng)我們想要更新頁面的狀態(tài)時(shí),也無法主動(dòng)改變頁面信息,因此,為了解決這類問題,F(xiàn)lutter又引入了元素樹和RenderObject樹。

元素樹與組件樹相對(duì)應(yīng),它由一個(gè)個(gè)元素(element)構(gòu)成。大部分情況下,其實(shí)我們可以把元素理解為展示在屏幕上的真正UI組件,它會(huì)根據(jù)我們?cè)诖a中配置的組件和屬性生成。因此,應(yīng)用開發(fā)者可以在代碼中創(chuàng)建的組件僅僅作為Flutter創(chuàng)建的元素的配置信息。當(dāng)應(yīng)用運(yùn)行并調(diào)用build()方法后,F(xiàn)lutter就會(huì)根據(jù)這些配置信息生成一個(gè)個(gè)與組件對(duì)應(yīng)的元素實(shí)例,在這個(gè)過程中創(chuàng)建了元素樹。

創(chuàng)建組件樹和元素樹有很多值得我們深思的益處,我們也會(huì)在之后的章節(jié)中持續(xù)地關(guān)注這個(gè)話題。

這里舉一個(gè)形象的例子來幫助讀者更深刻地理解組件和元素的含義。類似于公司的總經(jīng)理,組件的任務(wù)就是把近期的戰(zhàn)略部署(即配置信息)寫在紙上并下發(fā)給經(jīng)理人——元素,元素看到詳細(xì)的配置信息就開始干活。我們還需要注意一點(diǎn),總經(jīng)理隨時(shí)會(huì)改變戰(zhàn)略部署,而由于組件的不可變性,它并不會(huì)在原有的紙上修改,而只能拿一張新的白紙并重新寫下配置信息。這時(shí),經(jīng)理人——元素為了減少工作量需要將新的計(jì)劃與舊的計(jì)劃仔細(xì)比較,再采取相應(yīng)的更新措施。這就是Flutter框架層在此基礎(chǔ)上做的一部分優(yōu)化操作。問題又來了,元素作為經(jīng)理人很體面。當(dāng)然,元素不會(huì)把活全干完,于是又找了一個(gè)叫作RenderObject的員工來幫它做粗重的工作。

RenderObject在Flutter當(dāng)中負(fù)責(zé)頁面中組件的繪制和布局,其中會(huì)涉及的布局約束和繪制等技術(shù)會(huì)在第4章繼續(xù)深究。同時(shí),由RenderObject組成對(duì)應(yīng)的RenderObject樹(也稱為渲染樹)。最后,如果我們運(yùn)行如下這段帶有Center和Text兩個(gè)組件的代碼,最終Flutter內(nèi)部就會(huì)生成圖1.17所示的3棵樹,并最終顯示在手機(jī)屏幕中。

Center(
  child: Text('MeandNi'),
)

圖1.17 Flutter中的3棵樹

主站蜘蛛池模板: 哈尔滨市| 桂东县| 鄱阳县| 凤凰县| 内乡县| 通道| 四会市| 绥中县| 错那县| 吉木萨尔县| 尼玛县| 大余县| 平湖市| 宜兰市| 乌兰浩特市| 桐梓县| 酉阳| 大洼县| 蒙阴县| 武功县| 独山县| 松潘县| 西宁市| 沙河市| 萨嘎县| 措勤县| 乡城县| 汝南县| 荆门市| 舒兰市| 静海县| 谢通门县| 赫章县| 绥芬河市| 凤翔县| 德兴市| 循化| 昔阳县| 崇礼县| 肇州县| 乌拉特中旗|