There are some confusions about InheritedWidget
that I don't understand.
I have searched and read some QAs about InheritedWidget
on stackoverflow, but there are still things that I don't understand.
First of all, let's create a scenario.
This is my 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>();
}
}
and this is MyHomePage
that contains the MyInheritedWidget
. MyInheritedWidget
has two children: WidgetA
and a button that navigates to another screen, in this case 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'),
)
],
),
),
),
);
}
}
Inside WidgetA
there is a text widget that displays the name field from MyInheritedWidget
and another button that navigates to 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
and Page2
each has only a text widget that displays the name field from MyInheritedWidget
.
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),
);
}
}
In this scenario, the name field of MyInheritedWidget
is not accessible form Page1
and Page2
, but it can be accessed in WidgetA
.
Now lets get to the question:
It is said that an InheritedWidget
can be accessed from all of its descendants. What does descendant mean?
In MyHomePage
, I know WidgetA
is a descendant of MyInheritedWidget
. but, is Page1
also a descendant of MyInheritedWidget
?
If the answer is no, How can I make Page1
a descendant of MyInheritedWidget
?
Do I need to wrap it again inside MyInheritedWidget
?
What if there is a chain of navigations like this: Page1-> Page2 -> Page3 ... Page10 and I want to access MyInheritedWidget
in Page10, Do I have to wrap each of the pages inside MyInheritedWidget
?