8

I'm creating an application with the bottom navigator. I used a ShellRoute but our requirement is to hide bottom navigator on screen For example: main page can have bottom navigator when i go to another screen (such an user profile page) I have to hide bottom navigator but i use ShellRoute and sub route in the same ShellRoute, it doesn't hide bottom navigator.

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(),
                  ),
                ),
              ],
            ),

after that, i separate sub route into general route like below:

  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(),
          ),
        ),

and i use context.go(), it works but i can't back to previous screen with context.pop().

anyone has any idea?

krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
Unemploy
  • 119
  • 8

3 Answers3

4

This usually happens when the page doesn't know it's parent.

Specify that using parentNavigatorKey in GoRoute

Code Structure:

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
  

Suggestion

Your present code:

|_ShellKey
  |_GoRoute // needs bottomNav
  |_GoRoute // needs bottomNav
  |_GoRoute // doesn't need bottomNav

Change it to:

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

Refer detailed code and explaination of bottom NavigationBar using ShellRoute and GoRouter here

krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
3

I try this way, it works. use _navigatorKey and 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(),
                  ),
                ),
              ],
            ),
Unemploy
  • 119
  • 8
2

inside your main screen, where your navigation bar is defined, check your current location using GoRouter.of(context).location. if your location is not where bottomNavigationBar is suppose to show, then return Sizedbox or null , else return your 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
  • 1,438
  • 8
  • 18
  • good to hear that. also, consider upvoting if this answer helps you to help others find the right solution too. – john Nov 04 '22 at 08:39