Flutter

Flutter 「更新树」涉及到的问题

2019-03-13  本文已影响16人  黑键手记

上篇文章中,我们知道了 Flutter 的视图树中有三种树

Widget

Element

RenderObject

而且,Flutter 建议,Widget 最好是 不可变的(immutable)。

问题一

但是为什么呢?如果我们的页面数据发生变化,那么视图也需要发生变化,怎么办呢?

flutter 界面开发是一种响应式编程,主张 simle is fast

flutter 设计的初衷是希望数据变化时,发送通知到对应的可变更节点,这个节点可能是一个 StatefullWidget 子节点,也可能是 rootWidget,由上到下重新 create widget 树进行刷新。

重点是:重新 create widget树

这样的话,思路就比较简单了,就不用关心数据变更会影响到哪些节点了;
而且,将 widget 设置成不可变的,也节省了很多资源。

这个时候,问题二来了

问题二

更新数据,需要更新视图,就得重新创建 Widget ,那么 另外两颗树🌲也会重新创建吗?

当然不会啦~

如果需要再重新创建一遍,那么这种复杂度和使用 可变的 Widget 就基本没什么区别了。

widget 只是一个 数据结构的配置,是非常轻量的,耗费的资源也是很少的,再加上 flutter 团队对 widget 的创建、销毁都做了优化,所以不用担心整个 widget 树重新创建所带来的性能问题。

但是 RenderObject 就不一样了,RenderObject 涉及到 layout、paint 等复杂操作,是一个真正渲染的 view,整个 view 树重新创建开销就很大了。

既然这样,那么第三个问题也来了:

问题三

只重新创建 Widget ,不重新创建 Element 和 RenderObject,那么怎么实现「视图的更新」呢?

方便起见,大家看图吧~


视图树更新原则

需要注意:

element.child.widget == widget.build() 时,不会触发子树的 update,当触发 update 的时候,如果没有生效,要注意 widget 是否使用就 widget,没有 new widget,导致 update 流程走到改 widget 就停止了

子树的深度变化,会引起子树重建,如果子树是一个复杂度很高的树,可以使用 GlobalKey 作为子树 widget 的key。因为,GlobalKey 具有缓存功能。

问题四

怎样才能出发「视图树更新」即界面更新

总结

这几个问题,对于理解 Flutter 界面更新,应该有一定的帮助吧~~,图是自己对照着「语雀」上面的文章画的,大家有兴趣可以去看看

真心推荐

深入了解Flutter界面开发——作者:闲鱼技术-朝空

上一篇下一篇

猜你喜欢

热点阅读