【发布时间】:2021-03-31 06:32:15
【问题描述】:
关于InheritedWidget 有一些我不明白的困惑。
我在 stackoverflow 上搜索并阅读了一些关于 InheritedWidget 的 QA,但仍有一些我不明白的地方。
首先,让我们创建一个场景。
这是我的InheritedWidget:
class MyInheritedWidget extends InheritedWidget {
final String name;
MyInheritedWidget({
@required this.name,
@required Widget child,
Key key,
}) : super(key: key, child: child);
@override
bool updateShouldNotify(MyInheritedWidget oldWidget) =>
oldWidget.name != this.name;
static MyInheritedWidget of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
}
}
这是包含MyInheritedWidget 的MyHomePage。 MyInheritedWidget 有两个孩子:WidgetA 和一个导航到另一个屏幕的按钮,在本例中为 Page1。
class MyHomePage extends StatefulWidget {
@override
State createState() => new MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: Center(
child: MyInheritedWidget(
name: 'Name',
child: Column(
children: [
WidgetA(),
TextButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Page1(),
),
);
},
child: Text('Go to page 1'),
)
],
),
),
),
);
}
}
在WidgetA 内部有一个文本小部件,显示来自MyInheritedWidget 的name 字段和另一个导航到Page2 的按钮。
class WidgetA extends StatefulWidget {
@override
_WidgetAState createState() => _WidgetAState();
}
class _WidgetAState extends State<WidgetA> {
@override
Widget build(BuildContext context) {
final myInheritedWidget = MyInheritedWidget.of(context);
return Column(
children: [
Text(myInheritedWidget.name),
TextButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Page2(),
),
);
},
child: Text('Go to page 2'),
)
],
);
}
}
Page1 和 Page2 每个都只有一个文本小部件,用于显示来自 MyInheritedWidget 的 name 字段。
class Page1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
final myInheritedWidget = MyInheritedWidget.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Page 1'),
),
body: Text(myInheritedWidget.name),
);
}
}
class Page2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
final myInheritedWidget = MyInheritedWidget.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Page 2'),
),
body: Text(myInheritedWidget.name),
);
}
}
在这种情况下,MyInheritedWidget 的 name 字段无法通过Page1 和Page2 访问,但可以通过WidgetA 访问。
现在让我们来看看这个问题:
据说可以从其所有后代访问InheritedWidget。后裔是什么意思?
在MyHomePage 中,我知道WidgetA 是MyInheritedWidget 的后代。但是,Page1 也是MyInheritedWidget 的后代吗?
如果答案是否定的,我怎样才能让Page1 成为MyInheritedWidget 的后代?
我需要在MyInheritedWidget 中再次包装它吗?
如果有这样的导航链怎么办:Page1-> Page2 -> Page3 ... Page10我想在Page10中访问MyInheritedWidget,是否必须将每个页面都包装在MyInheritedWidget中?
【问题讨论】:
-
"[...] 但是,Page1 也是 MyInheritedWidget 的后代吗?" - 否
Page1不是MyInheritedWidget的后代 -Page1是主要Navigator的后代