flutter實踐 - Widget詳解

Widget是什么

Widget 是 Flutter 功能的抽象描述,是視圖的配置信息,同樣也是數(shù)據(jù)的映射,是 Flutter 開發(fā)框架中最基本的概念。前端框架中常見的名詞,比如視圖(View)、視圖控制器(View Controller)、活動(Activity)、應用(Application)、布局(Layout)等,在 Flutter 中都是 Widget。事實上,F(xiàn)lutter 的核心設計思想便是一切皆 Widget。所以,我們學習 Flutter,首先得從學會使用 Widget 開始。

Widget渲染過程

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

Widget.PNG

Widget

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

Element

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

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

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

Widget中的State

Widget有StatelessWidget和StatefulWidget兩種類型。StatefulWidget應對有交互需要動態(tài)變化效果的場景,StatelessWidget用于處理靜態(tài)的,無狀態(tài)的試圖展示。在 Flutter 中,Widget 采用由父到子、自頂向下的方式進行構建,父 Widget 控制著子 Widget 的顯示樣式,其樣式配置由父 Widget 在構建時提供。用這種方式構建出的 Widget,
有些(比如 Text、Container、Row、Column 等)在創(chuàng)建時,除了這些配置參數(shù)之外不依賴于任何其他信息,換句話說,它們一旦創(chuà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的使用。

總結

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

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374

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