如何在Flutter中使用GoRouter在特定路由中隐藏BottomNavigationBar?

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

How to hide BottomNavigationBar in specific routes using GoRouter in Flutter?

问题

在这段代码中,无论何时显示细节,底部导航栏(ButtomBar)都会一直显示。然而,我想在查看'a/details'时隐藏底部导航栏。有没有方法可以实现这个目标?

一种可能的方法是使用 navigationShell.shellRouteContext.routerState.matchedLocation.contains('details')。但我认为应该有一种更简单的方法。应该如何实现这个目标?

具体来说,我想根据以下部分当前显示的页面来确定是否启用或禁用底部导航栏。

class ScaffoldWithNavBar extends StatelessWidget {
  const ScaffoldWithNavBar({
    required this.navigationShell,
    required this.children,
    Key? key,
  }) : super(key: key ?? const ValueKey<String>('ScaffoldWithNavBar'));

  final StatefulNavigationShell navigationShell;

  /// ([AnimatedBranchContainer]).
  final List<Widget> children;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: AnimatedBranchContainer(
        currentIndex: navigationShell.currentIndex,
        children: children,
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Section A'),
          BottomNavigationBarItem(icon: Icon(Icons.work), label: 'Section B'),
        ],
        currentIndex: navigationShell.currentIndex,
        onTap: (int index) => _onTap(context, index),
      ),
    );
  }
}

请注意,这段代码的关键部分是如何在当前页面中切换底部导航栏的可见性,但要实现这个目标,可能需要在其他部分的代码中进行相应的更改。

英文:

https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/others/custom_stateful_shell_route.dart
In this code, the ButtomBar is always displayed even when details is displayed. However, I would like to hide the ButtomBar when I am viewing 'a/details'. Is there a way to do this?

One possible way to do this is to use navigationShell.shellRouteContext.routerState.matchedLocation.contains(&#39;details&#39;).
but I think there should be a simpler way. How should this be done?

Specifically, I would like to determine whether to enable or disable buttombar based on the page currently displayed in the following section.

class ScaffoldWithNavBar extends StatelessWidget {
  const ScaffoldWithNavBar({
    required this.navigationShell,
    required this.children,
    Key? key,
  }) : super(key: key ?? const ValueKey&lt;String&gt;(&#39;ScaffoldWithNavBar&#39;));

  final StatefulNavigationShell navigationShell;

  /// ([AnimatedBranchContainer]).
  final List&lt;Widget&gt; children;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: AnimatedBranchContainer(
        currentIndex: navigationShell.currentIndex,
        children: children,
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const &lt;BottomNavigationBarItem&gt;[
          BottomNavigationBarItem(icon: Icon(Icons.home), label: &#39;Section A&#39;),
          BottomNavigationBarItem(icon: Icon(Icons.work), label: &#39;Section B&#39;),
        ],
        currentIndex: navigationShell.currentIndex,
        onTap: (int index) =&gt; _onTap(context, index),
      ),
    );
  }

答案1

得分: 2

要在某些屏幕上隐藏底部导航栏,您可以在您提供的示例中进行以下更改:

首先创建两个GlobalKeys:

final GlobalKey<NavigatorState> _rootNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'root');
final GlobalKey<NavigatorState> _tabANavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'tabANav');

在您创建的GoRouter中,将_rootNavigatorKey分配给navigatorKey参数,如下所示:

final GoRouter _router = GoRouter(
    navigatorKey: _rootNavigatorKey,
    initialLocation: '/a',
    routes: <RouteBase>[
       ...
    ]
)

并且在您想要隐藏底部导航栏的shellRoutes中,例如在DetailsScreen中,将_rootNavigatorKey添加到parentNavigatorKey,如下所示:

GoRoute(
    path: 'details',
    parentNavigatorKey: _rootNavigatorKey,
    builder: (BuildContext context, GoRouterState state) =>
    const DetailsScreen(label: 'A'),
),

现在,当您转到或推送到详细信息屏幕时,底部导航栏将不会显示:

GoRouter.of(context).go('/a/details');

如果您有更多问题,可以向我提问,我将很乐意回答。

英文:

To hide bottom navigation bar on certain screens, you can make the following changes in the example you provided at:
https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/others/custom_stateful_shell_route.dart

First create two GlobalKeys:

final GlobalKey&lt;NavigatorState&gt; _rootNavigatorKey =
GlobalKey&lt;NavigatorState&gt;(debugLabel: &#39;root&#39;);
final GlobalKey&lt;NavigatorState&gt; _tabANavigatorKey =
GlobalKey&lt;NavigatorState&gt;(debugLabel: &#39;tabANav&#39;);

In the GoRouter you create, assign _rootNavigatorKey to navigatorKey parameter, like:

final GoRouter _router = GoRouter(
    navigatorKey: _rootNavigatorKey,
    initialLocation: &#39;/a&#39;,
    routes: &lt;RouteBase&gt;[
       ...
    ]
)

and to shellRoutes where you want to hide the bottom navigation bar, like DetailsScreen add _rootNavigatorKey to parentNavigatorKey, like:

                  GoRoute(
                    path: &#39;details&#39;,
                    parentNavigatorKey: _rootNavigatorKey,
                    builder: (BuildContext context, GoRouterState state) =&gt;
                    const DetailsScreen(label: &#39;A&#39;),
                  ),

Now when you go or push to details screen, the bottom navigation bar will not be shown.

GoRouter.of(context).go(&#39;/a/details&#39;);

If you have more questions, you can ask me and I'll be happy to answer them.

答案2

得分: 1

如果您为'a/details'页面分配了rootKey并使用push进行导航到该页面,我相信您的问题将得到解决。

GoRoute(
    path: 'details',
    parentNavigatorKey: _rootKey,
    builder: (BuildContext context, GoRouterState state) =>
    const DetailsScreen(label: 'A'),
),

并使用:

context.push('a/details');

不要忘记在DetailsScreenbuild函数中添加Scaffold

英文:

If you assign a rootKey to the 'a/details' page and perform navigation to that page using push, I believe your issue will be resolved.

GoRoute(
    path: &#39;details&#39;,
    parentNavigatorKey: _rootKey,
    builder: (BuildContext context, GoRouterState state) =&gt;
    const DetailsScreen(label: &#39;A&#39;),
),

and use

context.push(&#39;a/details&#39;);

do not forget to add Scaffold your DetailsScreen's build function

huangapple
  • 本文由 发表于 2023年7月28日 04:15:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76783122.html
匿名

发表评论

匿名网友

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

确定