Flutter 中的InheritedWidgets详解

InheritedWidget可以获取widget树的任何一级父widget的状态

当调用Loacle.of(context) 时

context -> BuildContext 实际上是Element的公共接口类, 为了防止直接对Element进行操作

abstract  class  Element extends DiagnosticableTree  implements  BuildContext

调动Element.dependOnInheritedWidgetsOfExactType

先查找ancestor 如果 ancestor 存在 _inheritedWidgets 中 (这个HashMap是在Element tree中传递的, 子Element继承 父Element的_inheritedWidgets表 , 如果在传递过程中,遇到InheritedElement 会将该Element加入这个Map)

关于_inheritedWidgets HashMap的维护

Element 的_updateInheritance() 实现 ,直接继承parent

InheritedElement对该方法的重写 : 加入添加本Element

src/widgets/framework.dart

abstract class Element

class InheritedElement extends ProxyElement

实际操作 _dependencies.add(ancestor) 将依赖的 InheritedElement加入维护的_dependencies Set中

调用 ancestor.updateDependencies(this, aspect)   -> this 就是当前的 context 也就是Element

被依赖的 InhreritedElement维护的 _dependents  Hashmap 也就会加入这个Element

_更新本element的 _denpendencies

Element维护了一个:

Map<Type,InheritedElement>_inheritedWidgets;

Set<InheritedElement>_dependencies;    < — 这个Set决定了 dependOnInheritedWidgetOfExactType 每一个Type只能有一个ancestor

将本element加入ancestor的 _denpendants;

等到 InheretedElement管理的InheritedWidget更新的时候:

会发生以下事件:

abstract class InheritedWidget extends ProxyWidget {

createElement() => InheritedElement()

updateShouldNotify(covariant InheritedWidget oldWidget)  covariant关键字 让override可以显示的指定子类型

final Map<Element, Object> _dependents = HashMap<Element, Object>(); 存放所有监听该InheritedElement的对象

当InheritedWidget更新的时候

遍历 _dependents for(finalElementdependentin_dependents.keys){

  1. 先assert 这个dependent真的是 本Element的descendent
  2. 调用notifyDependent(oldWidget, dependent) -> dependent.didChangeDependencies() 来通知状态更新

相关的类:

  • InheritedNotifier, an inherited widget whose value can be a Listenable, and which will notify dependents whenever the value sends notifications.
  • InheritedModel, an inherited widget that allows clients to subscribe to changes for subparts of the value.