级别: ★☆☆☆☆
标签:「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渲染流程”