Skip to content

Commit b8be37b

Browse files
tolonploi
authored andcommitted
[go_router] Nested stateful navigation with ShellRoute (flutter#2650)
Added functionality for building route configuration with support for preserving state in nested navigators. This change introduces a new shell route class called `StatefulShellRoute`, that uses separate navigators for its child routes as well as preserving state in each navigation branch. This is convenient when for instance implementing a UI with a `BottomNavigationBar`, with a persistent navigation state for each tab (i.e. building a `Navigator` for each tab). An example showcasing a UI with BottomNavigationBar and StatefulShellRoute has also been added ([`stateful_shell_route.dart`](https://github.com/tolo/flutter_packages/blob/nested-persistent-navigation/packages/go_router/example/lib/stateful_shell_route.dart)). Other examples of using `StatefulShellRoute` are also available in these repositories: * [stateful_books](https://github.com/tolo/stateful_books) - A fork of the Books example of go_router. * [stateful_navbar](https://github.com/tolo/stateful_navbar) - A clone of the Flutter Material 3 Navigation Bar example. <br/> Below is a short example of how a `StatefulShellRoute` can be setup: ```dart StatefulShellRoute( /// Each separate stateful navigation tree (i.e. Navigator) is represented by /// a StatefulShellBranch, which defines the routes that will be placed on that /// Navigator. StatefulShellBranch also makes it possible to configure /// things like an (optional) Navigator key, the default location (i.e. the /// location the branch will be navigated to when loading it for the first time) etc. branches: <StatefulShellBranch>[ StatefulShellBranch(navigatorKey: optionalNavigatorKey, routes: <RouteBase>[ GoRoute( path: '/a', builder: (BuildContext context, GoRouterState state) => const RootScreen(label: 'A'), routes: <RouteBase>[ GoRoute( path: 'details', builder: (BuildContext context, GoRouterState state) => const DetailsScreen(label: 'A'), ), ], ), ]), /// The default location of a branch will by default be the first of the /// configured routes. To configure a different route, provide the /// defaultLocation parameter. StatefulShellBranch(defaultLocation: '/b/detail', routes: <RouteBase>[ GoRoute( path: '/b', builder: (BuildContext context, GoRouterState state) => const RootScreen(label: 'B'), routes: <RouteBase>[ GoRoute( path: 'details', builder: (BuildContext context, GoRouterState state) => const DetailsScreen(label: 'B'), ), ], ), ]), ], /// Like ShellRoute, the builder builds the navigation shell around the /// sub-routes, but with StatefulShellRoute, this navigation shell is able to /// maintain the state of the Navigators for each branch. The navigation shell /// could for instance use a BottomNavigationBar or similar. builder: (BuildContext context, StatefulShellRouteState state, Widget child) => ScaffoldWithNavBar(shellState: state, body: child), ) ``` This fixes issue flutter/flutter#99124. It also (at least partially) addresses flutter/flutter#112267.
1 parent 3f008ef commit b8be37b

24 files changed

+4469
-342
lines changed

packages/go_router/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 7.1.0
2+
3+
- Introduces `StatefulShellRoute` to support using separate navigators for child routes as well as preserving state in each navigation tree (flutter/flutter#99124).
4+
- Updates documentation for `pageBuilder` and `builder` fields of `ShellRoute`, to more correctly
5+
describe the meaning of the child argument in the builder functions.
6+
- Adds support for restorationId to ShellRoute (and StatefulShellRoute).
7+
18
## 7.0.2
29

310
- Fixes `BuildContext` extension method `replaceNamed` to correctly pass `pathParameters` and `queryParameters`.

packages/go_router/example/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ An example to demonstrate how to use redirect to handle a synchronous sign-in fl
3030

3131
An example to demonstrate how to use handle a sign-in flow with a stream authentication service.
3232

33+
## [Stateful Nested Navigation](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/stateful_shell_route.dart)
34+
`flutter run lib/stacked_shell_route.dart`
35+
36+
An example to demonstrate how to use a `StatefulShellRoute` to create stateful nested navigation, with a
37+
`BottomNavigationBar`.
38+
3339
## [Books app](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/books)
3440
`flutter run lib/books/main.dart`
3541

packages/go_router/example/ios/Runner/Base.lproj/Main.storyboard

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<!--Flutter View Controller-->
99
<scene sceneID="tne-QT-ifu">
1010
<objects>
11-
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
11+
<viewController restorationIdentifier="sampleRestorationId" id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
1212
<layoutGuides>
1313
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
1414
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>

0 commit comments

Comments
 (0)