Using go_router package in a flutter app with a statefulShellRoute, how to navigate to routes outside of the shell?

huangapple go评论53阅读模式
英文:

Using go_router package in a flutter app with a statefulShellRoute, how to navigate to routes outside of the shell?

问题

我已经为底部导航栏在Flutter应用中实现了go_routerstatefulShellRoute以实现嵌套路由。

但是,我还有一些页面希望在statefulShellRoute之外(底部导航栏之外)。我在GoRouter中定义了这些路由,但当我使用context.push()导航到它们时,如预期的那样,我仍然可以看到底部导航栏,因为它将新屏幕推送到嵌套导航堆栈上。

如果我使用context.go(),虽然我可以到达页面并使底部导航栏消失,但现在无法返回,因为先前的路由被替换了。

如何在底部导航栏之外推送一个路由,并仍然具有返回的能力?

英文:

I have implemented go_router statefulShellRoute for bottomNavigationBar to have nested routes in a flutter app.

But I also have pages I want to be outside of the statefulShellRoute (outside bottom nav bar), i have these routes defined in GoRouter outside of the shell routes list but when I navigate to them using context.push(), as expected I can still see the Bottom Navigation Bar since it pushes the new screen onto the nested navigation stack.

If I use context.go(), even though I can reach the page and make the bottom nav bar disappear, I can't go back now since the previous route was replaced.

How can I push a route outside of the bottom navigation bar shell and still have the ability to come back?

答案1

得分: 5

以下是翻译好的部分:

"Was searching for the same question before. Here is the answer for future searchers: you need to assign parentNavigatorKey for your route to be pushed over shell route. Example from go_router repo (pay attention to _rootNavigatorKey):

final GoRouter _router = GoRouter(
navigatorKey: _rootNavigatorKey,
initialLocation: '/a',
debugLogDiagnostics: true,
routes: [
/// Application shell
ShellRoute(
navigatorKey: _shellNavigatorKey,
builder: (BuildContext context, GoRouterState state, Widget child) {
return ScaffoldWithNavBar(child: child);
},
routes: [
/// The first screen to display in the bottom navigation bar.
GoRoute(
path: '/a',
builder: (BuildContext context, GoRouterState state) {
return const ScreenA();
},
routes: [
// The details screen to display stacked on the inner Navigator.
// This will cover screen A but not the application shell.
GoRoute(
path: 'details',
builder: (BuildContext context, GoRouterState state) {
return const DetailsScreen(label: 'A');
},
),
],
),

/// Displayed when the second item in the the bottom navigation bar is
/// selected.
GoRoute(
path: '/b',
builder: (BuildContext context, GoRouterState state) {
return const ScreenB();
},
routes: [
/// Same as "/a/details", but displayed on the root Navigator by
/// specifying [parentNavigatorKey]. This will cover both screen B
/// and the application shell.
GoRoute(
path: 'details',
parentNavigatorKey: _rootNavigatorKey,
builder: (BuildContext context, GoRouterState state) {
return const DetailsScreen(label: 'B');
},
),
],
),

英文:

Was searching for the same question before. Here is the answer for future searchers: you need to assign parentNavigatorKey for your route to be pushed over shell route. Example from go_router repo (pay attention to _rootNavigatorKey):

  final GoRouter _router = GoRouter(
    navigatorKey: _rootNavigatorKey,
    initialLocation: '/a',
    debugLogDiagnostics: true,
    routes: <RouteBase>[
      /// Application shell
      ShellRoute(
        navigatorKey: _shellNavigatorKey,
        builder: (BuildContext context, GoRouterState state, Widget child) {
          return ScaffoldWithNavBar(child: child);
        },
        routes: <RouteBase>[
          /// The first screen to display in the bottom navigation bar.
          GoRoute(
            path: '/a',
            builder: (BuildContext context, GoRouterState state) {
              return const ScreenA();
            },
            routes: <RouteBase>[
              // The details screen to display stacked on the inner Navigator.
              // This will cover screen A but not the application shell.
              GoRoute(
                path: 'details',
                builder: (BuildContext context, GoRouterState state) {
                  return const DetailsScreen(label: 'A');
                },
              ),
            ],
          ),

          /// Displayed when the second item in the the bottom navigation bar is
          /// selected.
          GoRoute(
            path: '/b',
            builder: (BuildContext context, GoRouterState state) {
              return const ScreenB();
            },
            routes: <RouteBase>[
              /// Same as "/a/details", but displayed on the root Navigator by
              /// specifying [parentNavigatorKey]. This will cover both screen B
              /// and the application shell.
              GoRoute(
                path: 'details',
                parentNavigatorKey: _rootNavigatorKey,
                builder: (BuildContext context, GoRouterState state) {
                  return const DetailsScreen(label: 'B');
                },
              ),
            ],
          ),

huangapple
  • 本文由 发表于 2023年6月29日 00:45:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76575211.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定