flutter實踐 - Widget詳解

Widget是什么

Widget 是 Flutter 功能的抽象描述丧没,是視圖的配置信息鹰椒,同樣也是數(shù)據(jù)的映射,是 Flutter 開發(fā)框架中最基本的概念呕童。前端框架中常見的名詞漆际,比如視圖(View)、視圖控制器(View Controller)夺饲、活動(Activity)奸汇、應(yīng)用(Application)、布局(Layout)等往声,在 Flutter 中都是 Widget擂找。事實上,F(xiàn)lutter 的核心設(shè)計思想便是一切皆 Widget浩销。所以贯涎,我們學(xué)習(xí) Flutter,首先得從學(xué)會使用 Widget 開始慢洋。

Widget渲染過程

我們進行App開發(fā)時塘雳,最關(guān)注的問題就是:如何結(jié)構(gòu)化的組織視圖數(shù)據(jù),提供給渲染引擎從而完成頁面繪制且警,通常情況下粉捻,不同的UI框架處理方式也不同,但都會用到視圖樹(View Tree)的思想斑芜。
Flutter將視圖樹的概念進行了擴展肩刃,把視圖數(shù)據(jù)的組織和渲染抽象為:Widget,Element杏头,RenderObject三個部分盈包。他們的關(guān)系如下圖所示:

Widget.PNG

Widget

Widget 是 Flutter 世界里對視圖的一種結(jié)構(gòu)化描述,你可以把它看作是前端中的“控件”或“組件”醇王。Widget 是控件實現(xiàn)的基本邏輯單位呢燥,里面存儲的是有關(guān)視圖渲染的配置信息,包括布局寓娩、渲染屬性叛氨、事件響應(yīng)信息等呼渣。Flutter 將 Widget 設(shè)計成不可變的,所以當視圖渲染的配置信息發(fā)生變化時寞埠,F(xiàn)lutter 會選擇重建 Widget 樹的方式進行數(shù)據(jù)更新屁置,以數(shù)據(jù)驅(qū)動 UI 構(gòu)建的方式簡單高效。但是仁连,因為涉及到大量對象的銷毀和重建蓝角,所以會對垃圾回收造成壓力。不過饭冬,Widget 本身并不涉及實際渲染位圖使鹅,所以它只是一份輕量級的數(shù)據(jù)結(jié)構(gòu),重建的成本很低昌抠。另外患朱,由于 Widget 的不可變性,可以以較低成本進行渲染節(jié)點復(fù)用扰魂,因此在一個真實的渲染樹中可能存在不同的 Widget 對應(yīng)同一個渲染節(jié)點的情況麦乞,這無疑又降低了重建 UI 的成本。

Element

Element是Widget的一個實例化對象劝评,承載視圖構(gòu)建的上下文數(shù)據(jù)。
Flutter渲染過程倦淀,可以分為三步

  • 首頁通過Widget樹生成對應(yīng)的Element樹
  • 然后創(chuàng)建相應(yīng)的RenderObject并關(guān)聯(lián)到Element.renderObject屬性上
  • 最后構(gòu)建成RenderObject樹蒋畜,從而完成最終的渲染

Element同時持有Widget和RenderObject。但真正負責最后渲染的其實是RenderObject撞叽。既然如此姻成,為什么需要Element呢?
因為Widget具有不可變性愿棋,Element卻是可變的科展,Element樹這一層將Widget樹的變化做了抽象,可以只將真正修改的部分同步到真實的RenderObject樹上糠雨,最大程度降低對真實渲染視圖的修改才睹,提高渲染效率,而不是銷毀整個視圖樹重建甘邀。

Widget中的State

Widget有StatelessWidget和StatefulWidget兩種類型琅攘。StatefulWidget應(yīng)對有交互需要動態(tài)變化效果的場景,StatelessWidget用于處理靜態(tài)的松邪,無狀態(tài)的試圖展示坞琴。在 Flutter 中,Widget 采用由父到子逗抑、自頂向下的方式進行構(gòu)建剧辐,父 Widget 控制著子 Widget 的顯示樣式寒亥,其樣式配置由父 Widget 在構(gòu)建時提供。用這種方式構(gòu)建出的 Widget荧关,
有些(比如 Text溉奕、Container、Row羞酗、Column 等)在創(chuàng)建時腐宋,除了這些配置參數(shù)之外不依賴于任何其他信息,換句話說檀轨,它們一旦創(chuàng)建成功就不再關(guān)心胸竞、也不響應(yīng)任何數(shù)據(jù)變化進行重繪。這樣的 Widget 被稱為 StatelessWidget(無狀態(tài)組件)参萄。示意圖如下:


stateless.PNG

有一些Widget(比如Image卫枝、Checkbox)的展示,除了父Widget初始化時傳入的靜態(tài)配置之外讹挎,還需要處理用戶的交互或其內(nèi)部的數(shù)據(jù)變化校赤,并體現(xiàn)在UI上卢佣,示意圖如下:


stateful.PNG

從定義上來看瞭吃,StatefulWidget好像是萬能,任何場景都可以使用StatefulWidget拦焚,事實果真如此嗎怜奖?
回顧前面提到的Widget更新機制如果我們的根布局是一個StatefulWidget浑测,其State中每更新一次UI,都將是一整個頁面所有Widget的銷毀和重建歪玲。雖然Flutter內(nèi)部通過Element層可以最大程度的降低對真實渲染視圖的修改迁央。但大量的Widget對象的銷毀和重建是無法避免的。所以滥崩,我們在開發(fā)過程中岖圈。要做到正確評估你的試圖呈現(xiàn)需求,避免無謂的StatefulWidget的使用钙皮。

總結(jié)

命令式編程強調(diào)精確控制過程細節(jié)蜂科;而聲明式編程強調(diào)通過意圖輸出結(jié)果整體。對應(yīng)到 Flutter 中株灸,意圖是綁定了組件狀態(tài)的 State崇摄,結(jié)果則是重新渲染后的組件。在 Widget 的生命周期內(nèi)慌烧,應(yīng)用到 State 中的任何更改都將強制 Widget 重新構(gòu)建逐抑。其中,對于組件完成創(chuàng)建后就無需變更的場景屹蚊,狀態(tài)的綁定是可選項厕氨。這里“可選”就區(qū)分出了 Widget 的兩種類型进每,即:StatelessWidget 不帶綁定狀態(tài),而 StatefulWidget 帶綁定狀態(tài)命斧。當你所要構(gòu)建的用戶界面不隨任何狀態(tài)信息的變化而變化時田晚,需要選擇使用 StatelessWidget,反之則選用 StatefulWidget国葬。前者一般用于靜態(tài)內(nèi)容的展示贤徒,而后者則用于存在交互反饋的內(nèi)容呈現(xiàn)中。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汇四,一起剝皮案震驚了整個濱河市接奈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌通孽,老刑警劉巖序宦,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異背苦,居然都是意外死亡互捌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門行剂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秕噪,“玉大人,你說我怎么就攤上這事厚宰〕布郏” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵固阁,是天一觀的道長。 經(jīng)常有香客問我城菊,道長备燃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任凌唬,我火速辦了婚禮并齐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘客税。我一直安慰自己况褪,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布更耻。 她就那樣靜靜地躺著测垛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秧均。 梳的紋絲不亂的頭發(fā)上食侮,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天号涯,我揣著相機與錄音,去河邊找鬼锯七。 笑死链快,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的眉尸。 我是一名探鬼主播域蜗,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼噪猾!你這毒婦竟也來了霉祸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤畏妖,失蹤者是張志新(化名)和其女友劉穎脉执,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體戒劫,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡半夷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了迅细。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片巫橄。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖茵典,靈堂內(nèi)的尸體忽然破棺而出湘换,到底是詐尸還是另有隱情,我是刑警寧澤统阿,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布彩倚,位于F島的核電站,受9級特大地震影響扶平,放射性物質(zhì)發(fā)生泄漏帆离。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一结澄、第九天 我趴在偏房一處隱蔽的房頂上張望哥谷。 院中可真熱鬧,春花似錦麻献、人聲如沸们妥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽监婶。三九已至,卻和暖如春餐曼,著一層夾襖步出監(jiān)牢的瞬間压储,已是汗流浹背鲜漩。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留集惋,地道東北人孕似。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像刮刑,于是被迫代替她去往敵國和親喉祭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容