1 调用 BuildContext.dependOnInheritedWidgetOfExactType 查找离当前节点最近的InheritedWidget
T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({ Object? aspect })
2 在Element中的实现如下 _inheritedElements , _inheritedElements 存储的是从根节点一直到当前节点所有类型的 InheritedElement。
PersistentHashMap<Type, InheritedElement>? _inheritedElements;
@override
T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({Object? aspect}) {
assert(_debugCheckStateIsActiveForAncestorLookup());
final InheritedElement? ancestor = _inheritedElements == null ? null : _inheritedElements![T];
if (ancestor != null) {
return dependOnInheritedElement(ancestor, aspect: aspect) as T;
}
_hadUnsatisfiedDependencies = true;
return null;
}
3 找到指定类型的 InheritedElement,调用当前节点的dependOnInheritedElement
dependOnInheritedElement(ancestor, aspect: aspect)
3.1 第一个参数ancestor为找到的第一个指定的 InheritedWidget 3.2 aspect 一般为null
4 Element dependOnInheritedElement 实现如下
@override
InheritedWidget dependOnInheritedElement(InheritedElement ancestor, { Object? aspect }) {
_dependencies ??= HashSet<InheritedElement>();
_dependencies!.add(ancestor);
ancestor.updateDependencies(this, aspect);
return ancestor.widget as InheritedWidget;
}
4.1 _dependencies 为当前节点持有的一个set集合。换句话说就是当前节点会通过 _dependencies 存储跟自己有关系的 InheritedElement。
5 调用 InheritedElement.updateDependencies() 直接调用setDependencies 没有使用第二个参数
@protected
void updateDependencies(Element dependent, Object? aspect) {
setDependencies(dependent, null);
}
6 这里调用的是 ancestor(InheritedElement) 的setDependencies
final Map<Element, Object?> _dependents = HashMap<Element, Object?>();
@protected
void setDependencies(Element dependent, Object? value) {
_dependents[dependent] = value;
}
6.1 dependent就是当前的节点。value在 InheritedElement 中是null。
至此,当前节点中通过_dependencies 持有依赖的节点。Element中_dependents的keys 就是依赖自己的所有子节点。
7 刷新 回走 InheritedElement notifyClients
@override
void notifyClients(InheritedWidget oldWidget) {
assert(_debugCheckOwnerBuildTargetExists('notifyClients'));
for (final Element dependent in _dependents.keys) {
assert(() {
// check that it really is our descendant
Element? ancestor = dependent._parent;
while (ancestor != this && ancestor != null) {
ancestor = ancestor._parent;
}
return ancestor == this;
}());
// check that it really depends on us
assert(dependent._dependencies!.contains(this));
notifyDependent(oldWidget, dependent);
}
}
_dependents.keys 存储的就是所有依赖当前InheritedElement 的子节点
7.1 调用 notifyDependent,最终调用所有依赖当前节点的子节点的 didChangeDependencies
@protected
void notifyDependent(covariant InheritedWidget oldWidget, Element dependent) {
dependent.didChangeDependencies();
}
InheritedModel 与 SharedAppData 基于InheritedElement实现的更细粒度的刷新跟数据共享。