Skip to content

Commit 420755d

Browse files
authored
Nested Navigator state restoration predictive back examples (#153723)
I've updated these two examples to support state restoration of the navigation stack and verified that they work with predictive back in the tests. This was motivated by a worry that users are not properly setting up their navigation and that our examples are misleading them in the name of simplicity.
1 parent 203a19e commit 420755d

File tree

4 files changed

+430
-62
lines changed

4 files changed

+430
-62
lines changed

examples/api/lib/widgets/navigator_pop_handler/navigator_pop_handler.0.dart

Lines changed: 85 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,35 @@ class NavigatorPopHandlerApp extends StatelessWidget {
1616
@override
1717
Widget build(BuildContext context) {
1818
return MaterialApp(
19+
restorationScopeId: 'root',
1920
initialRoute: '/',
20-
routes: <String, WidgetBuilder>{
21-
'/': (BuildContext context) => _HomePage(),
22-
'/nested_navigators': (BuildContext context) => const NestedNavigatorsPage(),
21+
onGenerateRoute: (RouteSettings settings) {
22+
return switch (settings.name) {
23+
'/' => MaterialPageRoute<void>(
24+
settings: const RouteSettings(
25+
name: '/',
26+
),
27+
builder: (BuildContext context) {
28+
return _HomePage();
29+
},
30+
),
31+
'/nested_navigators' => MaterialPageRoute<void>(
32+
settings: const RouteSettings(
33+
name: '/nested_navigators',
34+
),
35+
builder: (BuildContext context) {
36+
return const _NestedNavigatorsPage();
37+
},
38+
),
39+
_ => MaterialPageRoute<void>(
40+
settings: const RouteSettings(
41+
name: 'unknown_page',
42+
),
43+
builder: (BuildContext context) {
44+
return const _UnknownPage();
45+
},
46+
),
47+
};
2348
},
2449
);
2550
}
@@ -43,7 +68,7 @@ class _HomePage extends StatelessWidget {
4368
title: const Text('Nested Navigator route'),
4469
subtitle: const Text('This route has another Navigator widget in addition to the one inside MaterialApp above.'),
4570
onTap: () {
46-
Navigator.of(context).pushNamed('/nested_navigators');
71+
Navigator.of(context).restorablePushNamed('/nested_navigators');
4772
},
4873
),
4974
],
@@ -53,14 +78,14 @@ class _HomePage extends StatelessWidget {
5378
}
5479
}
5580

56-
class NestedNavigatorsPage extends StatefulWidget {
57-
const NestedNavigatorsPage({super.key});
81+
class _NestedNavigatorsPage extends StatefulWidget {
82+
const _NestedNavigatorsPage();
5883

5984
@override
60-
State<NestedNavigatorsPage> createState() => _NestedNavigatorsPageState();
85+
State<_NestedNavigatorsPage> createState() => _NestedNavigatorsPageState();
6186
}
6287

63-
class _NestedNavigatorsPageState extends State<NestedNavigatorsPage> {
88+
class _NestedNavigatorsPageState extends State<_NestedNavigatorsPage> {
6489
final GlobalKey<NavigatorState> _nestedNavigatorKey = GlobalKey<NavigatorState>();
6590

6691
@override
@@ -71,36 +96,45 @@ class _NestedNavigatorsPageState extends State<NestedNavigatorsPage> {
7196
},
7297
child: Navigator(
7398
key: _nestedNavigatorKey,
99+
restorationScopeId: 'nested-navigator',
74100
initialRoute: 'nested_navigators/one',
75101
onGenerateRoute: (RouteSettings settings) {
76-
switch (settings.name) {
77-
case 'nested_navigators/one':
78-
final BuildContext rootContext = context;
79-
return MaterialPageRoute<void>(
80-
builder: (BuildContext context) => NestedNavigatorsPageOne(
81-
onBack: () {
82-
Navigator.of(rootContext).pop();
83-
},
84-
),
85-
);
86-
case 'nested_navigators/one/another_one':
87-
return MaterialPageRoute<void>(
88-
builder: (BuildContext context) => const NestedNavigatorsPageTwo(
89-
),
90-
);
91-
default:
92-
throw Exception('Invalid route: ${settings.name}');
93-
}
102+
final BuildContext rootContext = context;
103+
return switch (settings.name) {
104+
'nested_navigators/one' => MaterialPageRoute<void>(
105+
settings: const RouteSettings(
106+
name: 'nested_navigators/one',
107+
),
108+
builder: (BuildContext context) => _NestedNavigatorsPageOne(
109+
onBack: () {
110+
Navigator.of(rootContext).pop();
111+
},
112+
),
113+
),
114+
'nested_navigators/one/another_one' => MaterialPageRoute<void>(
115+
settings: const RouteSettings(
116+
name: 'nested_navigators/one',
117+
),
118+
builder: (BuildContext context) => const _NestedNavigatorsPageTwo(),
119+
),
120+
_ => MaterialPageRoute<void>(
121+
settings: const RouteSettings(
122+
name: 'unknown_page',
123+
),
124+
builder: (BuildContext context) {
125+
return const _UnknownPage();
126+
},
127+
),
128+
};
94129
},
95130
),
96131
);
97132
}
98133
}
99134

100-
class NestedNavigatorsPageOne extends StatelessWidget {
101-
const NestedNavigatorsPageOne({
135+
class _NestedNavigatorsPageOne extends StatelessWidget {
136+
const _NestedNavigatorsPageOne({
102137
required this.onBack,
103-
super.key,
104138
});
105139

106140
final VoidCallback onBack;
@@ -117,7 +151,7 @@ class NestedNavigatorsPageOne extends StatelessWidget {
117151
const Text('A system back here returns to the home page.'),
118152
TextButton(
119153
onPressed: () {
120-
Navigator.of(context).pushNamed('nested_navigators/one/another_one');
154+
Navigator.of(context).restorablePushNamed('nested_navigators/one/another_one');
121155
},
122156
child: const Text('Go to another route in this nested Navigator'),
123157
),
@@ -135,10 +169,8 @@ class NestedNavigatorsPageOne extends StatelessWidget {
135169
}
136170
}
137171

138-
class NestedNavigatorsPageTwo extends StatelessWidget {
139-
const NestedNavigatorsPageTwo({
140-
super.key,
141-
});
172+
class _NestedNavigatorsPageTwo extends StatelessWidget {
173+
const _NestedNavigatorsPageTwo();
142174

143175
@override
144176
Widget build(BuildContext context) {
@@ -162,3 +194,22 @@ class NestedNavigatorsPageTwo extends StatelessWidget {
162194
);
163195
}
164196
}
197+
198+
class _UnknownPage extends StatelessWidget {
199+
const _UnknownPage();
200+
201+
@override
202+
Widget build(BuildContext context) {
203+
return Scaffold(
204+
backgroundColor: Colors.grey.withBlue(180),
205+
body: const Center(
206+
child: Column(
207+
mainAxisAlignment: MainAxisAlignment.center,
208+
children: <Widget>[
209+
Text('404'),
210+
],
211+
),
212+
),
213+
);
214+
}
215+
}

0 commit comments

Comments
 (0)