阅读 630

Flutter中的Element(上篇)

级别: ★☆☆☆☆

标签:「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都会产生一个新的widgetframework 将使用新widget调用[update]方法,这个新的widget将总是拥有和旧widget同样的runtimeTypeKey。如果父节点希望改变树中此位置的新widget对应的runtimeTypeKey时,会unmount旧的element并且在此位置注入一个新的widget,(意味着使用新的widget创建一个新的element放在此位置)。

  • 还有一些时候呢,树中的祖先节点(或者中间的祖先),想要移除树中的某个element,该怎么办呢?祖先节点自己调用 [deactivateChild]

[deactivateChild]后会发生什么事情呢?祖先将从render tree中遍历移除elements对应的render objects,并且将这个元素加入到owner对应的不活跃的element数组中,最终导致framework对此element调用[deactivate]方法。

关于ownerBuildOwner类型的,它widgets framework的管理类

用于跟踪哪些widgets需要rebuild,并且处理一些适用于整个widget tree的其他任务。

  • 这个时候呢,element会进入inactive状态,并且不会出现在屏幕上。

一个element可以保持inactive状态直到当前的动画帧结束。在动画帧结束的时候,所有处于inactiveelements将会被unmounted(即:调用[unmount]方法)。

  • 但是,当处于inactive状态的元素被重新合并到树中时(比如:它或它的祖先有能重用的global key时),framework 将从ownerinactive elements数组中移除这个element,并且为此element调用[activate] ,同时 **reattach**此elementrender objectrender tree中。这时候呢,这个element将 再次变为active状态,并且可能出现字屏幕上。
  • 当处于inactive状态的elements,在当前动画帧结束的时候并没有被重新合并到树中时,framework 将为每个elements调用[unmount] 方法。
  • 到这时,element会变为defunct,并且以后将再也无法合并到树中(即宣告,element顽强而富有斗志的一生 end)。

Element的生命周期图解

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
奇舞周刊