
点击左上角QiShare,关注我们

级别:★☆☆☆☆
标签:「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的一些重要的方法的作用以及调用时机。
关注我们的途径有:QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)
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渲染流程”
奇舞团安卓团队——aTaller
奇舞周刊
了解更多iOS及相关新技术,请关注我们的公众号:



更多精彩内容,尽在