开始介绍inheritedWidget
之前,先来介绍一个 知识点 为后面的内容做铺垫
先介绍ancestorWidgetOfExactType
1. 先看下 Demo 代码结构
demo
地址: github.com/LZQL/flutte…
可以说是目前 全网 最完整的demo
演示了

2. ancestorWidgetOfExactType
返回给定类型的最近父widget
,该widget
的类型必须是具体widget
的子类。
一般来说,inheritFromWidgetOfExactType
更有用,因为继承的widget
将在更改时触发消费者重新构建。ancestorWidgetOfExactType
适用于交互事件处理程序(例如手势回调)或执行一次性任务,例如断言
您拥有或不具有作为特定类型的父widget
。widget
的构建方法的返回值不应该依赖于该方法返回的值,因为如果该方法的返回值发生更改,构建上下文将不会重新生成
。这可能会导致生成方法中使用的数据发生更改,但是没有重新生成widget
。
总结一下上面的意思:
ancestorWidgetOfExactType
一般用于 断言,是否有特定类型的父widget
ancestorWidgetOfExactType
可以用来获取父widget
的一些信息- 如果想要根据方法的返回值来判断是否重新构建,
ancestorWidgetOfExactType
并不适用
下面会分别给出 上面的3
点总结来给出demo
场景
1. 断言
这边就不给出自己的demo
,直接看源码,源码的应用场景说明一切,这边也是官方翻译的最好证明

Hero
的源码,做了断言,断言就写到这里
2. 获取父widget
的一些信息
1. 代码结构

2. 运行效果
WidgeC
是一个 加号按钮, 点击了WidgeC
,获取HomepageState
调用incrementCounter
方法,
, widgetA
,widgetB
,widgetC
会重新build
,看下图

3. 具体代码
代码位置 ancestor01.dart
/// ancestorWidgetOfExactType 获取父widget的一些信息
class MyAncestorTree01 extends StatefulWidget {
@override
_MyAncestorTree01State createState() => _MyAncestorTree01State();
}
class _MyAncestorTree01State extends State<MyAncestorTree01> {
@override
Widget build(BuildContext context) {
return TopPage01();
}
}
class TopPage01 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: HomePage(),
),
);
}
}
class HomePage extends StatefulWidget {
final HomePageState state = HomePageState();
@override
HomePageState createState() {
return state;
}
}
class HomePageState extends State<HomePage> {
int counter = 0;
void incrementCounter() {
setState(() {
counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
WidgetA(),
WidgetB(),
WidgetC(),
],
),
);
}
}
class WidgetA extends StatelessWidget {
@override
Widget build(BuildContext context) {
/// 获取 HomePageState 来获取 counter
final HomePage widget =
context.ancestorWidgetOfExactType(HomePage);
final HomePageState state = widget?.state;
return Center(
child: Text(
'${state == null ? 0 : state.counter}',
style: Theme.of(context).textTheme.display1,
),
);
}
}
class WidgetB extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('Widget B Text');
}
}
class WidgetC extends StatelessWidget {
@override
Widget build(BuildContext context) {
/// 获取 HomePageState 来 调用 加法操作
final HomePage widget = context.ancestorWidgetOfExactType(HomePage);
final HomePageState state = widget?.state;
return RaisedButton(
onPressed: () {
state?.incrementCounter();
},
child: Icon(Icons.add),
);
}
}
3. 子widget无法检测到父widget的更改
此demo
用来演示 子widget无法检测到父widget的更改
的具体情况
为后面的内容做铺垫
我将ancestorWidgetOfExactType
封装了一个 of 方法放到了TopPage02
里面,
与 2. 获取父widget 的一些信息
的使用场景不同。
1. 代码结构

2. 运行效果
注意看下图,当我点击了1 - AncestorWidgetOfExactType02 演示
按钮,进入 demo
页面,从右侧可以看出,因为是第一次进去,所以全部widget
都进行了build
操作,但是当我 点击 了Add item
按钮,TopPage02
会rebuild
但是WidgetA
, WidgetB
,WidgetC
,并不会进行rebuild

3. 具体代码
代码位置ancestor02.dart
/// ancestorWidgetOfExactType
/// 子widget无法检测到父widget的更改
/// (父widget rebuild 子widget no rebuild)
class MyAncestorTree02 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new TopPage02(
child: new Scaffold(
appBar: new AppBar(
title: new Text('Title'),
),
body: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new WidgetA(),
new WidgetB(),
new WidgetC(),
],
),
),
);
}
}
class Item {
String reference;
Item(this.reference);
}
class TopPage02 extends StatefulWidget {
TopPage02({
Key key,
this.child,
}) : super(key: key);
final Widget child;
final TopPage02State state = new TopPage02State();
@override
TopPage02State createState() {
return state;
}
static TopPage02State of(BuildContext context) {
/// 通过从 TopPage02 的 context 得到树结构来返回第一个 TopPage02State
return (context.ancestorWidgetOfExactType(TopPage02)
as TopPage02)
.state;
}
}
class TopPage02State extends State<TopPage02> {
List<Item> _items = <Item>[];
int get itemsCount => _items.length;
void addItem(String reference) {
setState(() {
_items.add(new Item(reference));
});
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}
class WidgetA extends StatefulWidget {
@override
_WidgetAState createState() => _WidgetAState();
}
class _WidgetAState extends State<WidgetA> {
@override
Widget build(BuildContext context) {
final TopPage02State state = TopPage02.of(context);
return new Center(
child: new RaisedButton(
child: new Text('WidgetA :Add Item'),
onPressed: () {
/// 这边调用 addItem 方法,但是WidgetA,WidgetB,WidgetC
/// 并不会 build
/// 这就说明了:widget的构建方法的返回值不应该依赖于该方法返回的值,
/// 因为如果该方法的返回值发生更改,构建上下文将不会重新生成。
/// 这可能会导致生成方法中使用的数据发生更改,但是没有重新生成widget
state.addItem('new item');
},
),
);
}
}
class WidgetB extends StatelessWidget {
@override
Widget build(BuildContext context) {
final TopPage02State state = TopPage02.of(context);
return new Text('widgetB itemCount:${state.itemsCount}');
}
}
class WidgetC extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Text('I am Widget C');
}
}
3. InheritedWidget
1. 什么是 InheritedWidget
特性:
InheritedWidget
是一个可以在树中高效地向下传递数据
的组件:我们可以在以InheritedWidget
为节点的树下任一Widget
中调用BuildContext.inheritFromWidgetOfExactType
来获取离其最近的InheritedWidget
实例- 当以上面这种方式(调用
inheritFromWidgetOfExactType
方法时)被引用后,每当InheritedWidget
自身的状态改变时,会导致“consumer”
(调用inheritFromWidgetOfExactType
方法的这个Child
) 重新build
第一点:在Flutter
中,正是通过InheritedWidget
来共享应用主题(Theme
)和Locale
(当前语言环境)信息的
第二点:解决了 上面提到ancestorWidgetOfExactType
的第三点不能通过返回值来进行重新build
的情况
InheritedWidget
的在Widget
树中数据传递方向是从上到下的,这和Notification
的传递方向正好相反。(后面系列文章介绍Notification
)
2. didChangeDependencies
StatefulWidget
的State
对象有一个回调didChangeDependencies
,它会在“依赖”发生变化时被Flutter Framework
调用。而这个“依赖”指的就是是否使用了父widget
中InheritedWidget
的数据,如果使用了,则代表有依赖,如果没有使用则代表没有依赖。这种机制可以使子组件在所依赖的主题、locale
等发生变化时有机会来做一些事情。
4. 通过 2 - InheritedWidget演示01
,发现问题
这个例子 是参照 book.flutterchina.club/chapter7/in… 写的一样,相信很多人都看过
1. 代码结构

2. 效果图
当我点击了 click me
按钮 加1,widgetA
,widgeB
,RaisedButton
会重新build

3. 代码
代码位置:inheritedwidget01.dart
/// InheritedWidget01 , 会导致 `widgetA`,` widgeB`,`RaisedButton `会重新`build`
class InheritedWidgetTest01 extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return InheritedWidgetTest01State();
}
}
class InheritedWidgetTest01State extends State<InheritedWidgetTest01> {
int tmpData = 0;
@override
Widget build(BuildContext context) {
print('InheritedWidgetTest01 build');
return Scaffold(
body: Center(
child: ShareInherited(
data: tmpData,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
WidgetA(),
WidgetB(),
RaisedButton(
child: Text("Click me"),
onPressed: () {
setState(() {
print('onPressed');
tmpData += 1;
});
},
),
],
),
),
),
);
}
}
class ShareInherited extends InheritedWidget {
final int data; //需要在子树中共享的数据,保存点击次数
ShareInherited({@required this.data, @required Widget child}) : super(child: child) {
print('ShareInherited construct');
}
/// 允许所有子 widget 通过包含的 context 获得最近的 ShareInherited 实例
/// 定义一个便捷方法,方便子树中的widget获取共享数据
/// 在内部,除了简单地返回 ShareInherited 实例外,它还订阅消费者 widget 以便用于通知更改
static ShareInherited of(BuildContext context) {
return context.inheritFromWidgetOfExactType(ShareInherited);
}
/// 用来告诉 InheritedWidget 如果对数据进行了修改,
/// 是否必须将通知传递给所有子 widget(已注册/已订阅)
@override
bool updateShouldNotify(ShareInherited oldWidget) {
// 如果返回true,则子树中依赖(build函数中有调用)本widget
// 的子widget的`state.didChangeDependencies`会被调用
bool result = oldWidget.data != this.data;
print('ShareInherited updateShouldNotify result = $result');
return result;
}
}
class WidgetA extends StatefulWidget {
@override
_WidgetAState createState() => _WidgetAState();
}
class _WidgetAState extends State<WidgetA> {
@override
Widget build(BuildContext context) {
print('WidgetA build');
int data = ShareInherited.of(context).data;
return Text('WidgetA data = $data');
}
@override
void didChangeDependencies() {
print('WidgetA didChangeDependencies');
super.didChangeDependencies();
}
}
class WidgetB extends StatefulWidget {
@override
_WidgetBState createState() => _WidgetBState();
}
class _WidgetBState extends State<WidgetB> {
@override
Widget build(BuildContext context) {
print('WidgetB build');
return Text('WidgetB');
}
@override
void didChangeDependencies() {
print('WidgetB didChangeDependencies');
super.didChangeDependencies();
}
}
4. 发现的现象
WidgetA
调用了inheritFromWidgetOfExactType
方法,获得了存放在 ShareInherited
对象里的data
数据并显示在WidgetA
内容上,同时使得 WidgetA
和ShareInherited
产生关联;
当点击 RaisedButton
触发InheritedWidgetTest01
状态更新时,InheritedWidgetTest01State
的 build
方法回调,重新构建 ShareInherited
对象传入新值,由于data
发生变化,ShareInherited
的方法updateShouldNotify
中返回了true
,最终使得与ShareInherited
关联的WidgetA
触发reBuild
。
当我们运行并点击RaisedButton
后,页面表现得确实如上述所示,WidgetA
的内容由 WidgetA data = 0
变为了WidgetA data = 1
,似乎 InheritedWidget
正确的使用方式正是如此,但是log
里输出的却是如下:
I/flutter (11303): onPressed
I/flutter (11303): InheritedWidgetTest01 build
I/flutter (11303): ShareInherited construct
I/flutter (11303): ShareInherited updateShouldNotify result = true
I/flutter (11303): WidgetA didChangeDependencies
I/flutter (11303): WidgetA build
I/flutter (11303): WidgetB build
可以看到,结合前面的代码逻辑分析,理论上只有 WidgetA
才会reBuild
,而现在却产生了I/flutter (11303): WidgetB build
这条记录。这是为什么呢?
5. 原因分析
其实可以从前面提到的特性2
找到答案。其中说到:InheriteWidget
状态发生变化时会rebuild
相关的child
。 我们知道,flutter
中Widget
被标识为了@immutable
,即是不可变的,那么所谓的状态发生变化就意味着InheriteWidget
重新构建,由于前面代码中在InheriteWidget
构造时同时也构造的其child
对象,因此当InheriteWidget
重新构建时也会导致child
跟着重新构建,这样也就失去了“rebuild相关的child”
的意义,
也就是说,要想特性2生效,需要保证
InheriteWidget
节点下的树不会被重新构建。
5. 解决方法1:使用 const Widget
将InheriteWidget
的child
转化为const
,这样即使在重建 InheriteWidget
时,由于其child
得到的是同一个对象,也就不会导致这个子树重建,选择性reBuild
也就得到了保证。但是由于const
特性,相关的参数也必须是常量,因此需要重写或修改的代码量相对较多,因此更推荐解决方法2
的做法,这个方法在后面回写
1. const demo 01,发现问题
1. 代码结构

2. 效果图
WidgeA
,WidgeB
,FlatButton
是处于同一级别的
从下图可以看到 当我点击了click me
,widgetB
并不会被 rebuild
, 但是 WidgeA
和FlatButton
会rebuild
,这样解决了WidgeB rebuild
的问题,但是 FlateButton
并不涉及到 页面的数据刷新,如果我想要让 FlatButton
也不rebuild
呢? 看const
的demo02

3. 代码
代码位置:inheritedwidget_const_01.dart
/// 使用 const
/// Widget A ,FlatButton rebuild, Widget B no rebuild
class InheritedWidgetConst01 extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return InheritedWidgetConst01State();
}
}
class InheritedWidgetConst01State extends State<InheritedWidgetConst01> {
int tmpData = 0;
@override
Widget build(BuildContext context) {
print('InheritedWidgetTest02 build');
return Scaffold(
body: Center(
child: ShareInherited(
data: tmpData,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const WidgetA(),
const WidgetB(),
FlatButton(
child: Text("Click me"),
onPressed: () {
setState(() {
print('onPressed');
tmpData += 1;
});
},
),
],
),
),
),
);
}
}
class ShareInherited extends InheritedWidget {
final int data;
ShareInherited({this.data, @required Widget child}) : super(child: child) {
print('ShareInherited construct');
}
@override
bool updateShouldNotify(ShareInherited oldWidget) {
bool result = oldWidget.data != this.data;
print('ShareInherited updateShouldNotify result = $result');
return result;
}
static ShareInherited of(BuildContext context) {
return context.inheritFromWidgetOfExactType(ShareInherited);
}
}
class WidgetA extends StatelessWidget {
const WidgetA();
@override
Widget build(BuildContext context) {
print('WidgetA build');
int data = ShareInherited.of(context).data;
return Text('WidgetA data = $data');
}
}
class WidgetB extends StatelessWidget {
const WidgetB();
@override
Widget build(BuildContext context) {
print('WidgetB build');
return Text('WidgetB');
}
}
2. const demo 02,继续发现问题
1. 代码结构

2. 效果图
你会发现,WidgeA
和 WidgeC
还是rebuild
, 要解决这个问题,就需要用到 文章顶部提到的ancestorWidgetOfExactType
了,看 const demo 03,终极写法

3. 代码
代码位置 inheritedwidget_const_02.dart
/// 使用 const
/// Widget A ,Widget C rebuild, Widget B no rebuild
class InheritedWidgetConst02 extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return InheritedWidgetConst02State();
}
}
class InheritedWidgetConst02State extends State<InheritedWidgetConst02> {
int tmpData = 0;
void addItem(){
setState(() {
tmpData++;
});
}
@override
Widget build(BuildContext context) {
print('InheritedWidgetTest02 build');
return Scaffold(
body: Center(
child: ShareInherited(
data: tmpData,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const WidgetA(),
const WidgetB(),
WidgetC(),
],
),
state: this,
),
),
);
}
}
class ShareInherited extends InheritedWidget {
final int data;
final InheritedWidgetConst02State state;
ShareInherited({this.data, @required Widget child,this.state}) : super(child: child) {
print('ShareInherited construct');
}
@override
bool updateShouldNotify(ShareInherited oldWidget) {
bool result = oldWidget.data != this.data;
print('ShareInherited updateShouldNotify result = $result');
return result;
}
static ShareInherited of(BuildContext context) {
return context.inheritFromWidgetOfExactType(ShareInherited);
}
}
class WidgetA extends StatelessWidget {
const WidgetA();
@override
Widget build(BuildContext context) {
print('WidgetA build');
int data = ShareInherited.of(context).data;
return Text('WidgetA data = $data');
}
}
class WidgetB extends StatelessWidget {
const WidgetB();
@override
Widget build(BuildContext context) {
print('WidgetB build');
return Text('WidgetB');
}
}
class WidgetC extends StatefulWidget {
@override
_WidgetCState createState() => _WidgetCState();
}
class _WidgetCState extends State<WidgetC> {
@override
Widget build(BuildContext context) {
print('Widge C build');
InheritedWidgetConst02State state = ShareInherited.of(context).state;
return FlatButton(
child: Text("Click me"),
onPressed: () {
setState(() {
print('onPressed');
state.addItem();
});
},
);
}
}
3. const demo 03,终极写法
1. 代码结构

2. 效果图
ShareInherited
的of
方法 ,增加了 是否 rebuild
的参数
你会发现 ,现在只有WidgeA
会rebuild
,完美啊
static ShareInherited of([BuildContext context, bool rebuild = true]) {
return (rebuild
? context.inheritFromWidgetOfExactType(ShareInherited)
: context.ancestorWidgetOfExactType(ShareInherited) );
}

3. 代码
代码位置inheritedwidget_const_03.dart
/// 使用 const
/// Widget A rebuild, Widget B Widget C no rebuild
class InheritedWidgetConst03 extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return InheritedWidgetConst03State();
}
}
class InheritedWidgetConst03State extends State<InheritedWidgetConst03> {
int tmpData = 0;
void addItem() {
setState(() {
tmpData++;
});
}
@override
Widget build(BuildContext context) {
print('InheritedWidgetTest02 build');
return Scaffold(
body: Center(
child: ShareInherited(
data: tmpData,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const WidgetA(),
const WidgetB(),
const WidgetC(),
],
),
state: this,
),
),
);
}
}
class ShareInherited extends InheritedWidget {
final int data;
final InheritedWidgetConst03State state;
ShareInherited({this.data, @required Widget child, this.state})
: super(child: child) {
print('ShareInherited construct');
}
@override
bool updateShouldNotify(ShareInherited oldWidget) {
bool result = oldWidget.data != this.data;
print('ShareInherited updateShouldNotify result = $result');
return result;
}
static ShareInherited of([BuildContext context, bool rebuild = true]) {
return (rebuild
? context.inheritFromWidgetOfExactType(ShareInherited)
: context.ancestorWidgetOfExactType(ShareInherited) );
}
}
class WidgetA extends StatelessWidget {
const WidgetA();
@override
Widget build(BuildContext context) {
print('WidgetA build');
int data = ShareInherited
.of(context)
.data;
return Text('WidgetA data = $data');
}
}
class WidgetB extends StatelessWidget {
const WidgetB();
@override
Widget build(BuildContext context) {
print('WidgetB build');
return Text('WidgetB');
}
}
class WidgetC extends StatelessWidget {
const WidgetC();
@override
Widget build(BuildContext context) {
print('Widge C build');
InheritedWidgetConst03State state = ShareInherited.of(context,false).state;
return FlatButton(
child: Text("Click me"),
onPressed: () {
print('onPressed');
state.addItem();
},
);
}
}
6. 解决方法2:上移Child
对象到InheriteWidget
的Parent Widget
1. out demo 01,发现问题
1. 代码结构

2. 效果图
具体看代码吧,稍显复杂 ,这边命名不是很规范,懒得改了, 太累了写demo
,看代码可以知道
class ShareInherited extends StatelessWidget
这里的ShareInherited
是一个 StatelessWidget
,也就是 上移了Child
对象到InheriteWidget
的Parent Widget
class _ShareInherited extends InheritedWidget
而_ShareInherited
才是 具体的 InheritedWidget
看下图可知 Widget A ,FlatButton rebuild, Widget B no rebuild
这时候我们 一样的 把 FlatButton
放到 WidgetC
然后上移到 InheriteWidget
的Parent Widget
看能不能实现让
WidgeC
no rebuild

3. 代码
代码位置inheritedwidget_out_01.dart
/// 上移`Child`对象到`InheriteWidget`的`Parent Widget`
/// Widget A ,FlatButton rebuild, Widget B no rebuild
class InheritedWidgetOut01 extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return InheritedWidgetOut01State();
}
}
class InheritedWidgetOut01State extends State<InheritedWidgetOut01> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: MyWidget(
Column(
children: <Widget>[
WidgetA(),
WidgetB()
],
)
),
);
}
}
class MyWidget extends StatefulWidget {
final Widget child;
MyWidget(this.child);
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
int tempData = 0;
@override
Widget build(BuildContext context) {
return ShareInherited(
data: tempData,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
widget.child,
FlatButton(
child: Text("Click me"),
onPressed: () {
setState(() {
print('onPressed');
tempData += 1;
});
},
)
],
),
),
);
}
}
class ShareInherited extends StatelessWidget {
final int data;
final Widget child;
ShareInherited({
Key key,
this.data,
this.child
}): assert(child != null),
assert(data != null),
super(key: key);
static int of(BuildContext context) {
final _ShareInherited inheritedTheme = context.inheritFromWidgetOfExactType(_ShareInherited);
return inheritedTheme.shareInherited.data;
}
@override
Widget build(BuildContext context) {
return _ShareInherited(shareInherited:this , child: child,);
}
}
class _ShareInherited extends InheritedWidget{
final ShareInherited shareInherited;
_ShareInherited({
Key key,
@required this.shareInherited,
@required Widget child,
}):assert(shareInherited != null),
super(key: key, child: child);
@override
bool updateShouldNotify(_ShareInherited oldWidget) {
return shareInherited.data != oldWidget.shareInherited.data;
}
}
class WidgetA extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('WidgetA build');
int data = ShareInherited.of(context);
return Text('WidgetA data = $data');
}
}
class WidgetB extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('WidgetB build');
return Text('WidgetB');
}
}
2. out demo 02,继续发现问题
1. 代码结构

2. 效果图
你会发现 Widget A ,Widget C rebuild, Widget B no rebuild
如果想要 让 Widge C no rebuild,看out demo 03

3. 代码
代码位置inheritedwidget_out_02.dart
/// 上移`Child`对象到`InheriteWidget`的`Parent Widget`
/// Widget A ,Widget C rebuild, Widget B no rebuild
class InheritedWidgetOut02 extends StatefulWidget {
@override
_InheritedWidgetOut02State createState() => new _InheritedWidgetOut02State();
}
class _InheritedWidgetOut02State extends State<InheritedWidgetOut02> {
@override
Widget build(BuildContext context) {
return new MyInheritedWidget(
child: new Scaffold(
appBar: new AppBar(
title: new Text('Title'),
),
body: Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[new WidgetA(), new WidgetB(), new WidgetC()],
),
),
),
);
}
}
class MyInheritedWidget extends StatefulWidget {
MyInheritedWidget({
Key key,
this.child,
}) : super(key: key);
final Widget child;
@override
MyInheritedWidgetState createState() => new MyInheritedWidgetState();
static MyInheritedWidgetState of([BuildContext context]) {
return (context.inheritFromWidgetOfExactType(_MyInherited) as _MyInherited).data;
// 通过从 MyInheritedWidget 的 context 得到树结构来返回第一个 MyInheritedWidgetState
}
}
class MyInheritedWidgetState extends State<MyInheritedWidget> {
int tempData = 0;
/// Helper method to add an Item
void addItem() {
setState(() {
tempData++;
});
}
@override
Widget build(BuildContext context) {
return new _MyInherited(
data: this,
child: widget.child,
);
}
}
class _MyInherited extends InheritedWidget {
_MyInherited({
Key key,
@required Widget child,
@required this.data,
}) : super(key: key, child: child);
final MyInheritedWidgetState data;
@override
bool updateShouldNotify(_MyInherited oldWidget) {
return true;
}
}
class WidgetA extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('Widget A build');
final MyInheritedWidgetState state = MyInheritedWidget.of(context);
return Text('WidgetA data = ${state.tempData}');
}
}
class WidgetB extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('Widget B build');
return Text('WidgetB');
}
}
class WidgetC extends StatefulWidget {
@override
_WidgetCState createState() => _WidgetCState();
}
class _WidgetCState extends State<WidgetC> {
@override
Widget build(BuildContext context) {
print('Widget C build');
final MyInheritedWidgetState state = MyInheritedWidget.of(context);
return RaisedButton(
child: Text("Click me"),
onPressed: () {
print('onPressed');
state.addItem();
},
);
}
}
3. out demo 03,终极写法
1. 代码结构

2. 效果图
因为这个demo
的 Perfomance
界面展示不够形象,就直接展示输出log
查看结果比较形象
可以发现 Widget A rebuild, Widget B Widget C no rebuild ,完美啊 ,写到这里已经要吐了

3. 代码
代码位置inheritedwidget_out_03.dart
/// 上移`Child`对象到`InheriteWidget`的`Parent Widget`
/// Widget A rebuild, Widget B Widget C no rebuild
class InheritedWidgetOut03 extends StatefulWidget {
@override
_InheritedWidgetOut03State createState() => new _InheritedWidgetOut03State();
}
class _InheritedWidgetOut03State extends State<InheritedWidgetOut03> {
@override
Widget build(BuildContext context) {
return new MyInheritedWidget(
child: new Scaffold(
appBar: new AppBar(
title: new Text('Title'),
),
body: Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[new WidgetA(), new WidgetB(), new WidgetC()],
),
),
),
);
}
}
class MyInheritedWidget extends StatefulWidget {
MyInheritedWidget({
Key key,
this.child,
}) : super(key: key);
final Widget child;
@override
MyInheritedWidgetState createState() => new MyInheritedWidgetState();
static MyInheritedWidgetState of(
[BuildContext context, bool rebuild = true]) {
return (rebuild
? context.inheritFromWidgetOfExactType(_MyInherited) as _MyInherited
: context.ancestorWidgetOfExactType(_MyInherited) as _MyInherited)
.data;
// 通过从 MyInheritedWidget 的 context 得到树结构来返回第一个 MyInheritedWidgetState
}
}
class MyInheritedWidgetState extends State<MyInheritedWidget> {
int tempData = 0;
/// Helper method to add an Item
void addItem() {
setState(() {
tempData++;
});
}
@override
Widget build(BuildContext context) {
return new _MyInherited(
data: this,
child: widget.child,
);
}
}
class _MyInherited extends InheritedWidget {
_MyInherited({
Key key,
@required Widget child,
@required this.data,
}) : super(key: key, child: child);
final MyInheritedWidgetState data;
@override
bool updateShouldNotify(_MyInherited oldWidget) {
return true;
}
}
class WidgetA extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('Widget A build');
final MyInheritedWidgetState state = MyInheritedWidget.of(context);
return Text('WidgetA data = ${state.tempData}');
}
}
class WidgetB extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('Widget B build');
return Text('WidgetB');
}
}
class WidgetC extends StatefulWidget {
@override
_WidgetCState createState() => _WidgetCState();
}
class _WidgetCState extends State<WidgetC> {
@override
Widget build(BuildContext context) {
print('Widget C build');
final MyInheritedWidgetState state = MyInheritedWidget.of(context, false);
return RaisedButton(
child: Text("Click me"),
onPressed: () {
print('onPressed');
state.addItem();
},
);
}
}
7. 两种解决方法,在源码中的应用
方法1 : 可以查看TickerMode
这个类
方法2: 可以查看 Theme
类
8. 参考文章
book.flutterchina.club/chapter7/in…
