級別: ★☆☆☆☆
標簽:「Flutter」「Element 」「生命周期 」
作者: 沐靈洛
審校: QiShare團隊
Element是什么?
Widget
在樹中特定位置的實例。文檔中的描述:
An instantiation of a [Widget] at a particular location in the tree.
widgets
描述如何配置一個子樹,但是相同的widget
可以同時被用來配置多個子樹,這是因為widget
是不可變的。一個Element
表示在樹中的特定位置對Widget
配置數據的使用。隨著時間的推移,Element
關聯的widget
可能會變化。比如:如果此位置的widget
對應的父widget
重新構建了,并且在此位置重新創建了一個新的widget
。
樹中的Elements
:大多數的element
的child
都是獨一無二的,但是有一些widgets
關聯的element
可以有多個children
,比如RenderObjectElement
的子類MultiChildRenderObjectElement
。
Element的生命周期
framework
通過在將要被用來作為element
的初始配置的widget
上調用[Widget.createElement]
創建一個element
。framework
通過調用[mount]
將一個新創建的element
加入樹中給定的父節點的插槽下面。[mount]
方法負責注入任何child widgets
并且在有需要的時候,會調用[attachRenderObject]
將關聯的render objects
添加到渲染樹render tree
中。
到這一步的時候element
,會進入active
狀態,并且會顯示在屏幕上。某些時候,父節點可能決定要改變使用在子
element
上的配置(widget
)時。比如:父節點因為一個新的state
重新build
,(每次build
都會產生一個新的widget
)framework
將使用新widget
調用[update]
方法,這個新的widget
將總是擁有和舊widget
同樣的runtimeType
和Key
。如果父節點希望改變樹中此位置的新widget
對應的runtimeType
或Key
時,會unmount
舊的element
并且在此位置注入一個新的widget
,(意味著使用新的widget
創建一個新的element
放在此位置)。還有一些時候呢,樹中的祖先節點(或者中間的祖先),想要移除樹中的某個
element
,該怎么辦呢?祖先節點自己調用[deactivateChild]
。
當[deactivateChild]
后會發生什么事情呢?祖先將從render tree
中遍歷移除elements
對應的render objects
,并且將這個元素加入到owner
對應的不活躍的element
數組中,最終導致framework
對此element
調用[deactivate]
方法。
關于
owner
是BuildOwner
類型的,它widgets framework
的管理類
用于跟蹤哪些widgets
需要rebuild
,并且處理一些適用于整個widget tree
的其他任務。
- 這個時候呢,
element
會進入inactive
狀態,并且不會出現在屏幕上。
一個element
可以保持inactive
狀態直到當前的動畫幀結束。在動畫幀結束的時候,所有處于inactive
的elements
將會被unmounted
(即:調用[unmount]
方法)。 - 但是,當處于
inactive
狀態的元素被重新合并到樹中時(比如:它或它的祖先有能重用的global key
時),framework
將從owner
的inactive elements
數組中移除這個element
,并且為此element
調用[activate]
,同時reattach
此element
的render object
到render tree
中。這時候呢,這個element
將 再次變為active
狀態,并且可能出現字屏幕上。 - 當處于
inactive
狀態的elements
,在當前動畫幀結束的時候并沒有被重新合并到樹中時,framework
將為每個elements
調用[unmount]
方法。 - 到這時,
element
會變為defunct
,并且以后將再也無法合并到樹中(即宣告,element
頑強而富有斗志的一生end
)。
Element的生命周期圖解
下一篇我們將與大家一起探討Element
的一些重要的方法的作用以及調用時機。
iOS 解決 [NSURL fileURLWithPath:] 對 # 的編碼問題
Xcode 調整導航目錄字體大小b
Swift 5.1 (21) - 泛型
Swift 5.1 (20) - 協議
Swift 5.1 (19) - 擴展
Swift 5.1 (18) - 嵌套類型
Swift 5.1 (17) - 類型轉換與模式匹配
淺談編譯過程
深入理解HTTPS
淺談 GPU 及 “App渲染流程”