06 InheritedWidget-3
综上所述,我们从先 Theme
入手。
如下方代码所示,通过给 MaterialApp
设置主题数据,通过 Theme.of(context)
就可以获取到主题数据并绑定使用。当 MaterialApp
的主题数据变化时,对应的 Widget 颜色也会发生变化,这是为什么呢(キ`゚Д゚´)!!?
///添加主题
new MaterialApp(
theme: ThemeData.dark()
);
///使用主题色
new Container( color: Theme.of(context).primaryColor,
通过源码一层层查找,可以发现这样的嵌套: MaterialApp -> AnimatedTheme -> Theme -> _InheritedTheme extends InheritedWidget
,所以通过 MaterialApp
作为入口,其实就是嵌套在 InheritedWidget 下。
如上图所示,通过 Theme.of(context)
获取到的主题数据,其实是通过 context.inheritFromWidgetOfExactType(_InheritedTheme)
去获取的,而 Element 中实现了 BuildContext 的 inheritFromWidgetOfExactType
方法,如下所示:
那么,还记得上面说的 _inheritedWidgets
吗?既然 InheritedElement
已经存在于 _inheritedWidgets 中,拿出来用就对了。
前文:InheritedWidget 内的
InheritedElement
,该 Element 属于特殊 Element, 主要增加了将自身也添加到映射关系表 _inheritedWidgets
最后,如下图所示,在 InheritedElement 中,notifyClients
通过 InheritedWidget
的 updateShouldNotify
方法判断是否更新,比如在 Theme的 _InheritedTheme
是:
bool updateShouldNotify(_InheritedTheme old) => theme.data != old.theme.data;
所以本质上 Theme、Redux 、 Scope Model、Localizations 的核心都是
InheritedWidget
。
学员评价