Flutter的三棵樹

“三棵樹”是 Flutter 渲染和構建UI的核心機制,理解它們對于掌握 Flutter 至關重要。這三棵樹分別是:

  1. Widget 樹

  2. Element 樹

  3. RenderObject 樹

它們協同工作,以實現 Flutter 的高性能渲染和高效的響應式編程模型。

Flutter 是聲明式的UI,它只需要描述UI是什么樣的,而不需要一步步地指揮框架如何去構建和更新這個界面。

為了更好的理解可先了解:命令式 UI 和 聲明式 UI

一、Flutter的三棵樹

1. Widget 樹 (What to render)

  • 是什么:Widget 是你用代碼聲明的UI配置。它是一個不可變的(immutable)描述,告訴 Flutter 這部分UI應該長什么樣子。你可以把它看作是一份藍圖

  • 特點

    • 輕量級:Widget 本身并不負責實際的渲染或狀態管理,它只持有最終的配置信息(如顏色、字體、尺寸等)。

    • 不可變:一旦創建就不能修改。當UI需要變化時,你必須創建一個新的 Widget。這種immutability使得Widget的創建和銷毀非常快速。

    • 組合性:復雜的UI由無數個簡單的小Widget嵌套組合而成(如Column?>?Row?>?Container?>?Text)。

例子:這段代碼就定義了一棵小小的 Widget 樹。

Container( // Widgetcolor: Colors.blue,child: Center( // Widgetchild: Text('Hello World'), // Widget),
);

2. Element 樹 (How to render & Where)

  • 是什么:Element 是 Widget 在UI樹中具體位置的實例化體現。它是連接 Widget 和 RenderObject 的粘合劑,負責管理UI的更新和生命周期。

  • 特點

    • 可變且有狀態:Element 是長壽命的,在UI重建時會持續存在(只要同一個位置的runtimeTypekey沒變)。

    • 職責

      1. 掛載:它持有對對應 Widget 和 RenderObject 的引用。

      2. 比較:當UI重建,新的 Widget 樹到來時,Element 會負責將新的 Widget 與它當前持有的舊 Widget 進行對比(Widget.canUpdate)。

      3. 更新:如果新的 Widget 和舊的 Widget 是同一類型(runtimeTypekey相同),Element 會更新自己持有的 Widget 引用,并告訴 RenderObject 是否需要更新(reconfigure)。

      4. 重建:如果對比失敗,Element 會銷毀舊的并創建新的 Element 和 RenderObject。

簡單來說,Element 決定了是復用現有的UI結構,還是銷毀重建。

3. RenderObject 樹 (Actually rendering)

  • 是什么:RenderObject 是真正負責布局(Layout)和繪制(Paint)?的核心組件。它計算每個UI元素的大小和位置,并將它們繪制到屏幕上。

  • 特點

    • 重量級:布局和繪制的計算成本很高,因此 RenderObject 的創建和更新需要非常謹慎。

    • 核心方法

      • performLayout():計算自身和子節點的大小和位置。

      • paint():將自己繪制到畫布(Canvas)上。

    • 持久化:只要有可能,Flutter 會極力避免重新創建和重新布局 RenderObject,以保持渲染性能的流暢。

大多數開發者通常不直接操作 RenderObject,而是通過熟悉的 Widget(如Container,?Stack,?Align)來間接使用它們。

二、三棵樹如何協同工作?

讓我們通過一個簡單的計數器例子來看整個流程:

初始構建階段

  1. 你編寫了?MyHomePage?Widget 樹。

  2. Flutter 遍歷你的 Widget 樹,自上而下地創建對應的?Element

  3. 每個 Element 又會調用 Widget 的?createRenderObject()?方法,創建相應的?RenderObject

  4. 三棵樹都構建完畢,RenderObject 樹進行布局和繪制,UI顯示在屏幕上。

更新階段

(當你按下按鈕,counter增加)

??????????????
  1. setState(() { _counter++; })?被調用,標記該 StatefulWidget 的 Element 為“臟”狀態。

  2. 下一幀到來時,Flutter 會觸發重建對應的 Widget 子樹。build?方法被再次調用,返回一棵新的?Text($_counter)?Widget。

  3. 關鍵的對比過程(Diff)

    • 對應的 Element 會拿著這個新的?Text?Widget,與它當前持有的舊的?Text?Widget 進行比較。

    • 它發現兩者的?runtimeType?都是?Text,并且都沒有設置?key,所以可以更新。

  4. 高效的更新

    • Element 簡單地更新它持有的 Widget 引用為新的 Widget。

    • 然后,Element 會通知它對應的 RenderObject:“配置有變化,你需要更新了”。

    • RenderObject 檢查發現只是文本內容變了,它可能會標記自己需要重繪(repaint),但通常不需要重新布局(relayout)(因為文字大小可能沒變)。

  5. 下一幀,RenderObject 只進行必要的重繪,新的數字就顯示出來了。

三、為什么需要三棵樹? (優點)

  1. 性能優化:將輕量級的、不可變的 Widget 與重量級的、可變的 RenderObject 分離。UI的頻繁重建(創建新Widget)成本極低,而真正昂貴的布局和繪制過程只有在必要時才進行。

  2. 高效的響應式編程:通過 Element 樹的 Diff 算法,Flutter 可以精確地知道UI的哪一部分發生了變化,從而只更新必要的 RenderObject,而不是整個界面。這比傳統的命令式UI(如Android/iOS原生)手動操作View要高效得多。

  3. 邏輯與渲染分離:開發者只需關心如何用 Widget 描述UI(聲明式),而無需關心具體的渲染細節和更新邏輯,框架幫你處理了所有復雜性。

四、總結

角色特點職責
Widget 樹藍圖/配置輕量、不可變描述UI元素應該是什么樣子
Element 樹粘合劑/管理者可變、長壽命管理Widget的更新,決定是復用還是重建UI
RenderObject 樹渲染工人重量級、持久負責實際的布局、繪制工作,計算尺寸和位置,渲染到屏幕

簡單記憶Widget 是配置,Element 是管家,RenderObject 是干活的。?管家(Element)根據新的圖紙(Widget)來決定是讓工人(RenderObject)在原基礎上修改,還是直接換一個新工人。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921404.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921404.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921404.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

同一臺nginx中配置多個前端項目的三種方式

目錄 第一種方式:配置多個二級域名 第二種方式:配置端口轉發(不推薦) 第三種方式:同一個server中基于location配置(重點講解) 第一種方式:配置多個二級域名 一個域名下面申請多個二級域名,每個二級域名配置一個vue前端項目,這個很好配置,在這里不再詳細說明。 …

第二家公司雖然用PowerBI ,可能更適合用以前的QuickBI

第二家公司雖然用PowerBI ,可能更適合用以前的QuickBI現在回想一下,第二家公司數據源是MySQL ,常規報表是用excel報表,另外還做了一張能發布到web的看板供運營使用。基于基本情況,quickbi 的早期版本是合適的&#xff…

STM32 USBx Device HID standalone 移植示例 LAT1466

關鍵字:USBx, Device, HID,standalone 1.設計目的 目前 USBx Device standalone 的官方示例較少,不過使用 STM32CubeMX 可以快速地生成 USBx Device 相關類的示例工程,會很方便大家的開發。這里以 NUCLEO-H563 為例&…

python創建并寫入excel文件

大家好,這里是七七,今天來跟大家分享一個python創建并寫入一個excel文件的小例子,話不多說,開始介紹。首先我們來看一下這一小段代碼。import openpyxl# 創建一個新的 Excel 工作簿workbook openpyxl.Workbook()# 獲取當前活動的…

react native 出現 FATAL EXCEPTION: OkHttp Dispatcher

react native 出現 FATAL EXCEPTION: OkHttp Dispatcher 報錯信息FATAL EXCEPTION: OkHttp DispatcherProcess: , PID: 8868java.lang.NoSuchMethodError: No virtual method toString(Z)Ljava/lang/String; in class Lokhttp3/Cookie; or its super classes (declaration of o…

sentinel實現控制臺與nacos數據雙向綁定

有兩種方式可以實現&#xff1a;Springboot客戶端做相應配置&#xff08;推薦&#xff09;修改sentinel-dashboard的源碼一、Springboot客戶端做相應配置&#xff08;推薦&#xff09;1、添加依賴<dependency><groupId>com.alibaba.csp</groupId><artifac…

Kubernetes (k8s)

Kubernetes (k8s) 以下是一份 ?Kubernetes (k8s) 基礎使用教程&#xff0c;涵蓋從環境搭建到核心操作的完整流程&#xff0c;附詳細命令和示例&#xff1a; &#x1f680; ?一、環境準備&#xff08;3種方式&#xff09;?? ?1. 本地開發環境&#xff08;推薦&#xff09;?…

三打ANSYS HFSS

2. 激勵方式&#xff08;端口&#xff09;詳細對比分析在HFSS中&#xff0c;“激勵方式”和“端口”這兩個詞經常混用&#xff0c;但嚴格來說&#xff0c;“端口”是實現“激勵”的一種最主要的方式。端口類型工作原理適用情況優點缺點波端口 (Wave Port)默認首選。計算端口的固…

3.python——數據類型轉換

python的數據類型轉換分為兩種&#xff1a; 隱式轉換&#xff1a;自動完成 顯式轉換&#xff1a;用類型函數轉換 隱式轉換 # 自動轉為浮點數 num_int 123 num_flo 1.23num_new num_int num_flo顯式轉換 整型 x int(1) # x 輸出結果為 1 y int(2.8) # y 輸出結果為 2 z …

迅為RK3568開發板OpenHarmonyv3.2-Beta4版本測試-命令終端

將串口連接到開發板的調試串口&#xff0c;進入 OpenHarmony 系統后&#xff0c;會自動進入 OpenHarmony終端&#xff0c;如下圖所示&#xff1a;

【面試題】介紹一下BERT和GPT的訓練方式區別?

BERT(雙向編碼器): 預訓練任務: 掩碼語言模型(MLM):隨機掩蓋15%的token,其中: 80%替換為[MASK] 10%替換為隨機token 10%保持原樣 下一句預測(NSP):判斷兩個句子是否連續(后續版本已移除) 訓練特點: 使用雙向Transformer編碼器 同時利用左右上下文信息 適合理解類任…

邪修實戰系列(1)

1、第一階段邪修實戰總覽&#xff08;9.1-9.30&#xff09; 把第一階段&#xff08;基礎夯實期&#xff09;的學習計劃拆解成極具操作性的每日行動方案。這個計劃充分利用我“在職學習”的特殊優勢&#xff0c;強調“用輸出倒逼輸入”&#xff0c;確保每一分鐘的學習都直接服務…

XR數字融合工作站打造智能制造專業學習新范式

智能制造是工業4.0的核心發展方向&#xff0c;涵蓋數字化設計、智能生產、工業機器人、數字孿生、物聯網等關鍵技術。然而&#xff0c;傳統教學模式在設備成本高、實訓風險大、抽象概念難理解等方面存在諸多挑戰。XR數字融合工作站,利用VR/AR/MR等技術&#xff0c;通過虛擬仿真…

基于FPGA實現數字QAM調制系統

基于FPGA實現數字QAM調制系統題目要求一、代碼設計1.頂層2.分頻3.m序列4.串轉并5.映射6.正弦波余弦波生成ROM和7.ask二、仿真波形總結題目要求 FPGA實現數字QAM調制系統要求根據正交振幅調制原理&#xff0c;利用正弦載波信號發生器&#xff0c;實現調制信號。調制原理會利用到…

DAY 22 復習日

浙大疏錦行復習日 仔細回顧一下之前21天的內容&#xff0c;沒跟上進度的同學補一下進度。 作業&#xff1a; 自行學習參考如何使用kaggle平臺&#xff0c;寫下使用注意點&#xff0c;并對下述比賽提交代碼 導入需要的庫 import pandas as pd # 用于數據處理和分析&#xff0c;…

biocmanager安裝 庫 老是提示網絡連接錯誤 才嘗試各種辦法

您好&#xff0c;遇到 BioManager &#xff08;通常是 BiocManager&#xff09;安裝R包時提示網絡連接錯誤確實非常令人頭疼。這通常與R/RStudio的配置、網絡環境&#xff08;尤其是國內用戶&#xff09;或SSL證書問題有關。 請不要著急&#xff0c;我們可以按照從易到難的順序…

【開題答辯全過程】以 智能商品數據分析系統為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人&#xff0c;語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

解構復雜財務逆向業務:如何優雅地生成與管理負數單?

文章目錄一 核心復雜性二 關鍵設計模式&#xff1a;三 棘手場景與解決方案&#xff1a;1.分批合并處理&#xff1a;負數單需能智能拆分&#xff0c;精準沖銷多批次的正向單據。2.優先級問題&#xff1a;3.超額處理&#xff1a;系統應堅決攔截而非處理&#xff0c;防止資金損失和…

Android集成OpenCV4實例

Android集成OpenCV4分以下幾步驟&#xff1a; 使用Android Studio Giraffe | 2022.3.1創建一個Empty Views Activity空項目&#xff0c;包名為&#xff1a;com.example.andopencvdemo00 &#xff0c; 創建成功后&#xff0c;進行以下相關設置&#xff1a; 第一步&#xff1a;在…

npy可視化方法

npviewer 是一個應用程序&#xff0c;它允許您以熱圖的形式可視化 numpy 的 npy 文件中的數據。該應用程序根據不同的模式自動選擇適當的維度進行顯示。 根據不同的模式自動選擇適當的維度進行顯示支持不同格式的 numpy 數據的可視化&#xff0c;如 RGB 和灰度用戶友好的界面使…