我如何在ShellRoute上隐藏底部导航栏?

9
我正在使用底部导航器创建一个应用程序。 我使用了一个ShellRoute,但我们的要求是在屏幕上隐藏底部导航器。 例如: 主页面可以有底部导航器,当我转到另一个屏幕(如用户个人资料页面)时, 我必须隐藏底部导航器,但我使用ShellRoute和同一ShellRoute中的子路由,它不会隐藏底部导航器。
ShellRoute(
          navigatorKey: _shellNavigatorKey,
          builder: (context, state, child) {
            return MainScreen(child: child);
          },
          routes: [
            GoRoute(
              path: '/$dashboardRouteName',
              name: dashboardRouteName,
              pageBuilder: (context, state) => CustomPageRouteBuilder.route(
                key: UniqueKey(),
                child: const DashboardScreen(),
              ),
              routes: [
                GoRoute(
                  path: leaveRequestRouteName,
                  name: '$dashboardRouteName/$leaveRequestRouteName',
                  pageBuilder: (context, state) => CustomPageRouteBuilder.route(
                    key: state.pageKey,
                    child: const LeaveRequestScreen(),
                  ),
                ),
                GoRoute(
                  path: switchHolidayRouteName,
                  name: '$dashboardRouteName/$switchHolidayRouteName',
                  pageBuilder: (context, state) => CustomPageRouteBuilder.route(
                    key: state.pageKey,
                    child: const SwitchHolidayScreen(),
                  ),
                ),
              ],
            ),

接着,我将子路由分离成以下通用路由:

  ShellRoute(
          navigatorKey: _shellNavigatorKey,
          builder: (context, state, child) {
            return MainScreen(child: child);
          },
          routes: [
            GoRoute(
              path: '/$dashboardRouteName',
              name: dashboardRouteName,
              pageBuilder: (context, state) => CustomPageRouteBuilder.route(
                key: UniqueKey(),
                child: const DashboardScreen(),
              ),
            ),
....
 GoRoute(
          path: '/$switchHolidayRouteName',
          name: switchHolidayRouteName,
          pageBuilder: (context, state) => CustomPageRouteBuilder.route(
            key: state.pageKey,
            child: const SwitchHolidayScreen(),
          ),
        ),
        GoRoute(
          path: '/$leaveRequestRouteName',
          name: leaveRequestRouteName,
          pageBuilder: (context, state) => CustomPageRouteBuilder.route(
            key: state.pageKey,
            child: const LeaveRequestScreen(),
          ),
        ),

我使用 context.go(),它可以工作,但无法使用 context.pop() 返回到上一个屏幕。

有人有任何想法吗?

3个回答

4

当页面不知道其父级时,通常会发生这种情况。

GoRoute中使用parentNavigatorKey来指定它。

代码结构:

final _parentKey = GlobalKey<NavigatorState>();
final _shellKey = GlobalKey<NavigatorState>();

|_ GoRoute
 |_ parentNavigatorKey = _parentKey    Specify key here
|_ ShellRoute
 |_ GoRoute
  |_ parentNavigatorKey = _shellKey    Specify key here
 |_ GoRoute
  |_ parentNavigatorKey = _shellKey    Specify key here
  

抱歉,我只能提供英文到其他语言的翻译。
|_ShellKey
  |_GoRoute // needs bottomNav
  |_GoRoute // needs bottomNav
  |_GoRoute // doesn't need bottomNav

将其更改为:

|_ShellKey
  |_GoRoute // needs bottomNav
  |_GoRoute // needs bottomNav
|_GoRoute // doesn't need bottomNav  Try to keep it outside the ShellKey

请参考这里,详细查看ShellRouteGoRouter实现底部导航栏的代码和解释。


3

我尝试了这种方式,它有效。使用_navigatorKey和parentNavigatorKey。

final _navigatorKey = GlobalKey<NavigatorState>();
final _shellNavigatorKey = GlobalKey<NavigatorState>();
...
ShellRoute(
          navigatorKey: _shellNavigatorKey,
          builder: (context, state, child) {
            return MainScreen(child: child);
          },
          routes: [
            GoRoute(
              path: '/$dashboardRouteName',
              name: dashboardRouteName,
              pageBuilder: (context, state) => CustomPageRouteBuilder.route(
                key: UniqueKey(),
                child: const DashboardScreen(),
              ),
              routes: [
                GoRoute(
                  path: leaveRequestRouteName,
                  parentNavigatorKey: _navigatorKey,
                  name: '$dashboardRouteName/$leaveRequestRouteName',
                  pageBuilder: (context, state) => CustomPageRouteBuilder.route(
                    key: state.pageKey,
                    child: const LeaveRequestScreen(),
                  ),
                ),
                GoRoute(
                  path: switchHolidayRouteName,
                  parentNavigatorKey: _navigatorKey,
                  name: '$dashboardRouteName/$switchHolidayRouteName',
                  pageBuilder: (context, state) => CustomPageRouteBuilder.route(
                    key: state.pageKey,
                    child: const SwitchHolidayScreen(),
                  ),
                ),
              ],
            ),

你能提供源代码或者告诉我如何导航到/返回“不需要底部导航栏”的屏幕吗? - Khamidjon Khamidov

3

在你的主屏幕中,在导航栏定义的位置,使用GoRouter.of(context).location检查你的当前位置。如果你的位置不在应该显示bottomNavigationBar的地方,则返回SizedBox或null,否则返回你的BottomNavigationBar。

  @override
  Widget build(BuildContext context) {
    final location = GoRouter.of(context).location;
    print('goRouter Location $location');
    return Scaffold(
      body: widget.child,
      bottomNavigationBar: location != '/home' ? null : BottomNavigationBar(),
    );
  }


很高兴听到这个消息。如果这个答案对您有帮助,也请考虑点赞以帮助其他人找到正确的解决方案。 - john

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接