-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[go_router] Nested stateful navigation with ShellRoute #2650
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
fa4c542
76b17ae
7612a55
62574bd
850f41a
1c04588
1db6bba
6028c90
5f2e995
461efd9
0315e1a
510ec34
e82647a
e38fa32
f38b9bf
89f1dd7
3a00a54
b0a6264
b729d64
3b3909f
f0b2a1b
eb6d4d3
016be76
4ae26d7
4a9889a
1f3f01a
3b38641
d701ab5
bb6240d
245d47b
bda571b
da1ea0b
59c19e7
723de76
4c0a91d
7556965
ee9bde9
e9a7029
59a6b05
06ab1e9
1b877c8
e542a05
2215a51
b180653
8fdfb82
9240ea4
93bce8e
20dc0c6
376e80f
2b2ff91
5c9fe04
81e1296
59e3b66
8636bf8
1c509f1
42c7b7d
62e7fc1
9a7069a
ae48ede
141fdc1
b6b289f
4d05d99
d4edd47
7b9de47
703815c
9f88928
5ca533d
f5f0ecb
4a2eac3
fc7bd54
a65f9df
816acb2
ee2a845
89b82c5
90b9d62
7392264
c0253f6
2c4afa1
845c052
193a267
37c4969
c562482
38b5772
db22bac
d8d1641
4c4b7b0
f08f548
6f1b047
07ee030
9ffff5c
e9d40ee
0ea48cb
4abcaa9
ce23558
351ceb2
4cb0f1e
e6a4f71
873bf34
5b668f8
565c3cd
5ee1a8f
358551f
f9a2608
87211aa
257a272
08148e5
c18941f
b1ce762
75e43d0
9f54b4e
1226f44
881be86
6bbbd29
fd5412f
a5234a6
b9428cb
ee047c8
ddc71f0
5041bea
01cce04
9315373
89341ef
2c298cd
4c22b53
a7d419f
7285788
9983887
ad43837
3a83007
ec6722c
9bb0da9
a1c7a8f
477b47c
7f25f0c
6f35636
bb5c08f
16c095c
a18a5a5
abbd01b
0f36623
316cf8c
79a0c63
3696448
763b136
2f48831
709ee7a
bb7fd9e
9eaf1af
527a806
86a72e1
57b761f
85fa0b6
d75c5e2
bd1c018
c13cd71
c7b1295
0f842ee
80c396f
04b549a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,7 +16,7 @@ final GlobalKey<NavigatorState> _tabANavigatorKey = | |
| // navigation state is maintained separately for each tab. This setup also | ||
| // enables deep linking into nested pages. | ||
| // | ||
| // This example demonstrates how to display routes within a StatefulShellRoute, | ||
| // This example demonstrates how to display routes within a StackedShellRoute, | ||
| // that are places on separate navigators. The example also demonstrates how | ||
tolo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // state is maintained when switching between different tabs (and thus branches | ||
| // and Navigators). | ||
|
|
@@ -40,10 +40,10 @@ class NestedTabNavigationExampleApp extends StatelessWidget { | |
| builder: (BuildContext context, GoRouterState state) => | ||
| const ModalScreen(), | ||
| ), | ||
| StatefulShellRoute( | ||
| branches: <StatefulShellBranch>[ | ||
| StackedShellRoute( | ||
| branches: <StackedShellBranch>[ | ||
| /// The route branch for the first tab of the bottom navigation bar. | ||
| StatefulShellBranch( | ||
| StackedShellBranch( | ||
| navigatorKey: _tabANavigatorKey, | ||
| routes: <RouteBase>[ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this only take a single RouteBase? I can see the behavior difference with a single RouteBase vs multiple RouteBases when you switch to a different uri. but multiple RouteBases may make route parsing a bit complex. Also it is hard to keep track if you may have duplicated GoRoute in different branch. Is that a use case that require multiple RouteBases?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, I think the main reason was to better support redirection and the possibility to have different root routes for a branch, depending on the application state.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think that can be a valid use case. Does branch has priority? for example, if a string location would match two different branch, does one take priority over the other. If so, how the priorty is design. We should definitely document the behavior. If the branch should not have priority, we should add an assert that the route can't overlap.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure any priority is needed, but I guess an overlap check could be good. But perhaps such a check should be added for all routes, not just for StatefulShellRoute branches, or is there something preventing such a check (apart from parametrised routes making such check a bit harder)?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is ok for subroutes to overlaps for example this is valid in this case you can do special handling for a specific match in a wild card match, but I am not sure about branches if there are multiple root route though... maybe that is ok?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Late response to this (possible answered elsewhere), but this should be fine - overlapping routes should work the same as in other places. The only difference is that StatefulShellRoute needs to determine which Navigator a sub-route should be placed on (handled in A related thing that I realised though, is that there probably needs to be an assertion to check that the |
||
| GoRoute( | ||
|
|
@@ -67,7 +67,7 @@ class NestedTabNavigationExampleApp extends StatelessWidget { | |
| ), | ||
|
|
||
| /// The route branch for the second tab of the bottom navigation bar. | ||
| StatefulShellBranch( | ||
| StackedShellBranch( | ||
| /// It's not necessary to provide a navigatorKey if it isn't also | ||
| /// needed elsewhere. If not provided, a default key will be used. | ||
| // navigatorKey: _tabBNavigatorKey, | ||
|
|
@@ -98,18 +98,18 @@ class NestedTabNavigationExampleApp extends StatelessWidget { | |
| ), | ||
|
|
||
| /// The route branch for the third tab of the bottom navigation bar. | ||
| StatefulShellBranch( | ||
| /// StatefulShellBranch will automatically use the first descendant | ||
| StackedShellBranch( | ||
| /// StackedShellBranch will automatically use the first descendant | ||
| /// GoRoute as the initial location of the branch. If another route | ||
| /// is desired, specify the location of it using the defaultLocation | ||
| /// parameter. | ||
| // defaultLocation: '/c2', | ||
tolo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| routes: <RouteBase>[ | ||
| StatefulShellRoute( | ||
| StackedShellRoute( | ||
| /// This bottom tab uses a nested shell, wrapping sub routes in a | ||
| /// top TabBar. | ||
| branches: <StatefulShellBranch>[ | ||
| StatefulShellBranch(routes: <GoRoute>[ | ||
| branches: <StackedShellBranch>[ | ||
| StackedShellBranch(routes: <GoRoute>[ | ||
| GoRoute( | ||
| path: '/c1', | ||
| builder: (BuildContext context, GoRouterState state) => | ||
|
|
@@ -129,7 +129,7 @@ class NestedTabNavigationExampleApp extends StatelessWidget { | |
| ], | ||
| ), | ||
| ]), | ||
| StatefulShellBranch(routes: <GoRoute>[ | ||
| StackedShellBranch(routes: <GoRoute>[ | ||
| GoRoute( | ||
| path: '/c2', | ||
| builder: (BuildContext context, GoRouterState state) => | ||
|
|
@@ -150,21 +150,21 @@ class NestedTabNavigationExampleApp extends StatelessWidget { | |
| ), | ||
| ]), | ||
| ], | ||
| builder: (BuildContext context, StatefulShellRouteState state, | ||
| builder: (BuildContext context, StackedShellRouteState state, | ||
| Widget child) { | ||
| /// This nested StatefulShellRoute demonstrates the use of a | ||
| /// This nested StackedShellRoute demonstrates the use of a | ||
| /// custom container (TabBarView) for the branch Navigators. | ||
| /// Here, the default branch Navigator container (`child`) is | ||
| /// ignored, and the class StatefulNavigationShell is | ||
| /// ignored, and the class StackedNavigationShell is | ||
| /// instead used to provide access to the widgets representing | ||
| /// the branch Navigators (`List<Widget> children`). | ||
| /// | ||
| /// See TabbedRootScreen for more details on how the children | ||
| /// are used in the TabBarView. | ||
| return StatefulNavigationShell( | ||
| return StackedNavigationShell( | ||
| shellRouteState: state, | ||
| containerBuilder: (BuildContext context, | ||
| StatefulShellRouteState state, | ||
| StackedShellRouteState state, | ||
| List<Widget> children) => | ||
| TabbedRootScreen(shellState: state, children: children), | ||
| ); | ||
|
|
@@ -173,18 +173,18 @@ class NestedTabNavigationExampleApp extends StatelessWidget { | |
| ], | ||
| ), | ||
| ], | ||
| builder: (BuildContext context, StatefulShellRouteState state, | ||
| Widget child) { | ||
| builder: | ||
| (BuildContext context, StackedShellRouteState state, Widget child) { | ||
| /// This builder implementation uses the default container for the | ||
| /// branch Navigators (provided in through the `child` argument). This | ||
| /// is the simplest way to use StatefulShellRoute, where the shell is | ||
| /// is the simplest way to use StackedShellRoute, where the shell is | ||
| /// built around the Navigator container (see ScaffoldWithNavBar). | ||
| return ScaffoldWithNavBar(shellState: state, body: child); | ||
| }, | ||
|
|
||
| /// If it's necessary to customize the Page for StatefulShellRoute, | ||
| /// If it's necessary to customize the Page for StackedShellRoute, | ||
| /// provide a pageBuilder function instead of the builder, for example: | ||
| // pageBuilder: (BuildContext context, StatefulShellRouteState state, | ||
| // pageBuilder: (BuildContext context, StackedShellRouteState state, | ||
| // Widget child) { | ||
| // return NoTransitionPage<dynamic>( | ||
| // child: ScaffoldWithNavBar(shellState: state, body: child)); | ||
|
|
@@ -215,8 +215,8 @@ class ScaffoldWithNavBar extends StatelessWidget { | |
| Key? key, | ||
| }) : super(key: key ?? const ValueKey<String>('ScaffoldWithNavBar')); | ||
|
|
||
| /// The current state of the parent StatefulShellRoute. | ||
| final StatefulShellRouteState shellState; | ||
| /// The current state of the parent StackedShellRoute. | ||
| final StackedShellRouteState shellState; | ||
|
|
||
| /// Body, i.e. the container for the branch Navigators. | ||
| final Widget body; | ||
|
|
@@ -461,8 +461,8 @@ class TabbedRootScreen extends StatefulWidget { | |
| const TabbedRootScreen( | ||
| {required this.shellState, required this.children, super.key}); | ||
|
|
||
| /// The current state of the parent StatefulShellRoute. | ||
| final StatefulShellRouteState shellState; | ||
| /// The current state of the parent StackedShellRoute. | ||
| final StackedShellRouteState shellState; | ||
|
|
||
| /// The children (Navigators) to display in the [TabBarView]. | ||
| final List<Widget> children; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.