Flutter 开发实战

235课时
1K学过
8分

课程评价 (0)

请对课程作出评价:
0/300

学员评价

暂无精选评价
2分钟

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 下。

img

如上图所示,通过 Theme.of(context) 获取到的主题数据,其实是通过 context.inheritFromWidgetOfExactType(_InheritedTheme) 去获取的,而 Element 中实现了 BuildContextinheritFromWidgetOfExactType 方法,如下所示:

img

那么,还记得上面说的 _inheritedWidgets 吗?既然 InheritedElement 已经存在于 _inheritedWidgets 中,拿出来用就对了。

前文:InheritedWidget 内的 InheritedElement ,该 Element 属于特殊 Element, 主要增加了将自身也添加到映射关系表 _inheritedWidgets

最后,如下图所示,在 InheritedElement 中,notifyClients 通过 InheritedWidgetupdateShouldNotify 方法判断是否更新,比如在 Theme_InheritedTheme 是:

bool updateShouldNotify(_InheritedTheme old) => theme.data != old.theme.data;

img

所以本质上 Theme、Redux 、 Scope Model、Localizations 的核心都是 InheritedWidget