Widget
控件層,在flutter中,Container、Text等組件都屬于Widget,所以我們將這種樹稱為Widget樹,也可以叫做控件樹,他就表示我們在dart代碼中所寫的控件的結構
Element
Widget的另一種抽象,也可以把它看作一個更為實際控件,因為在我們的手機屏幕上顯示的控件并非我們代碼中所寫的Widget,我們在代碼中所使用的像 Container、Text等這類組件和其屬性只不過是我們想要構建的組件的配置信息,當我們第一次調用 build()方法想要在屏幕上顯示這些組件時,Flutter會根據這些信息生成該Widget控件對應的Element,同樣地,Element 也會被放到相應的Element樹中,在Flutter中,一個Widget通過多次復用可以對應多個Element實例,Element才是我們真正在屏幕上顯示的元素。
Element 與 Widget 另一個區別在于,Widget天然是不可變的(immutable),他如要更新便需要重建,如果想要把可變狀態與Widget聯系起來,可以使用StatefulWidget,StatefulWidget通過使用StatefulWidget.createState 方法創建 State對象,并將之擴充到Element以及合并到樹中;
Widget統治者Element,Widget有點像class生成對象Element
Widget【將軍】 ->Element 【百夫長】->RenderObject【士兵】
RenderObject
在flutter中做組件布局渲染的工作,其為了組件間的渲染搭配及布局約束也有對應的RenderObject樹,我們稱之為渲染樹。
組件渲染過程簡述
我們知道控件樹中的每個控件都會實現一個RenderObject對象做渲染任務,并將所有RenderObject組成渲染樹。Flutter渲染組件的過程如下:
Full Pipeline
User Input -> Animation -> Build -> Layout -> Paint -> Composite -> Rasterize
Flutter的渲染過程由用戶的輸入開始,當接受到用戶輸入的信號時,就會觸發動畫的進度更新,例如我們第一次渲染時的啟動動畫,或者我們在滾動手機屏幕時單個列表項復用時的移動動畫。之后便需要開始視圖數據的構建,(build),這一步中Flutter創建了前文描述的三顆視圖樹
在這之后,視圖才會進行布局(layout),計算各個部分的大小,然后進行繪制(paint),生成每個視圖的視覺數據,這部分的任務主要就是由 RenderObject所做 。這里,flutter中的布局過程可用下圖表示,在上述構建完成渲染樹后,父渲染對象會將布局約束信息向下傳遞,子渲染對象根據自己的渲染情況返回Size,Size數據會向上傳遞,最終父渲染對象完成布局過程
[圖片上傳失敗...(image-69c615-1567218514793)]
最后一步進行“光柵化”(Rasterize),前一步得到合成的視圖數據其實還是一份矢量描述數據,光柵化幫助把這份數據真正的生成一個一個的像素填充數據。在flutter中,光柵化這個步驟被放在Engine層中。
在日常開發學習中,我們只需要在代碼層中配置好我們的Widget樹,了解各種Widget特性及使用方法,其余的工作都可以交給我們的框架層去實現。
渲染樹詳解
渲染樹上每個節點都是一個繼承自 RenderObject 類的對象,其由Element中的renderObject或