flutter-状态管理2-inheritedWidget探究

2021-04-14  本文已影响0人  浮华_du

inheritedWidget是如何实现数据共享的?

要解决这个问题,首先我们先看下,这个数据是如何存取的,又是如何刷新的.

一. _inheritedWidgets的存取

这个问题的奥秘其实就在Element中.


element内部有一个_inheritedWidgets.png

我们先来看一下inheritedWidget数据共享使用过程中的这个Map存取:

取:

通常我们使用inheritedWidget的时候,都是会有一个取数据的过程,这个时候我们会通过子节点的BuildContext(Element是BuildContext的实现类,使用context.getElementForInheritedWidgetOfExactType() 或 context.dependOnInheritedWidgetOfExactType来获取到这个widget或element从而获取到数据(例如上次讲的例子).

image.png

查看这两个方法,在Element中,都是从 _inheritedWidgets这个map里取值,泛型T是key


Element中的实现.png

存:

Element中.png

InhertiedElement中重写了这个_updateInheritance()方法:
若父节点的_inheritedWidgets不为空,将其深拷贝给子节点的_inheritedWidgets;
若父节点的_inheritedWidgets为空,初始化一个Map,key为其widget的runtimeType


InhertiedElement中.png

我们可以看到,element中有Map<Type, InheritedElement>? _inheritedWidgets成员变量,这个成员变量一般情况下是空的,只有当父控件或本身是InheritedWidget的时候, _inheritedWidgets才会被初始化.
当父控件是InheritedWidget是,这个Map会在Element中被一级一级的向下传递与合并.

image.png

二. dependOnInheritedWidgetOfExactType方法中到底做了什么

通过element中对此方法的描述及InheritedElement中此方法的实现,可以看出:

三. getElementForInheritedWidgetOfExactType与dependOnInheritedWidgetOfExactType的区别

image.png

通过上图我们也可以看出, 两个方法的主要区别在于, getElementForInheritedWidgetOfExactType是直接获取了_inheritedWidgets内的InheritedElement返回;而dependOnInheritedWidgetOfExactType在获取的过程中,还多做了一步_dependents的管理,将_inheritedWidgets中的依赖关系管理起来

当inheritedWidget被更新时, _dependents中的element会被逐个执行notifyDependent,最后触发markNeedsBuild进行重绘.


image.png
image.png image.png

当执行notifyDependent时,会触发Element的didChangeDependencies方法,将_didChangeDependencies置为true,从而触发State的didChangeDependencies的回调生命周期


image.png
image.png

总结

所以,当我们inheritedWidget来实现数据共享的时候,需要注意两个点

上一篇下一篇

猜你喜欢

热点阅读