Flutter: Nested navigation inside a page using go_router
Asked Answered
A

2

8

In my Flutter app, I use go_router to navigate between pages.

Here are the current pages in my app:

  • accounts_page
  • add_account_page
  • import_accounts_page

Now, I would like to implement nested navigation inside add_account_page, so I can add a new account using multiple steps, let's say:

  • account_info_step
  • account_type_step
  • account_detail_step

Here is what I tried:


  final _navigatorKey = GlobalKey<NavigatorState>();
  final _addAccountNavigatorKey = GlobalKey<NavigatorState>();

  late final router = GoRouter(
    navigatorKey: _navigatorKey,
    initialLocation: "/accounts_page",
    routes: [
      ShellRoute(
        navigatorKey: _addAccountNavigatorKey,
        builder: (context, state, child) => AddAccountPage(child: child),
        routes: [
          GoRoute(
            parentNavigatorKey: _addAccountNavigatorKey,
            name: "account_info_step",
            path: "/account_info_step",
            builder: (context, state) => const AccountInfoStep(),
          ),
          GoRoute(
            parentNavigatorKey: _addAccountNavigatorKey,
            name: "account_type_step",
            path: "/account_type_step",
            builder: (context, state) => const AccountTypeStep(),
          ),
          GoRoute(
            parentNavigatorKey: _addAccountNavigatorKey,
            name: "account_detail_step",
            path: "/account_detail_step",
            builder: (context, state) => const AccountDetailStep(),
          ),
        ],
      ),
      GoRoute(
        name: "accounts_page",
        path: "/accounts_page",
        pageBuilder: (context, state) => const AccountsPage(),
      ),
      GoRoute(
        name: "import_accounts_page",
        path: "/import_accounts_page",
        pageBuilder: (context, state) => const ImportAccountsPage(),
      ),
    ],
  );

And then I call context.pushNamed("account_info_step"), but nothing happens.

Is it possible then to use go_router to implement nested navigation inside add_account_page and if yes, how?

Thanks.

Ancona answered 17/2, 2023 at 15:19 Comment(0)
R
8

I think the way you are trying to create nested navigation is not right. Also you don't need to use ShellRoute, you can use shell route if you want to create something like a persistent bottom navigation bar and changing only the child while keeping the bottom nav bar at the bottom.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:untitled/homepage.dart';
import 'package:untitled/test_page.dart';

final _navigatorKey = GlobalKey<NavigatorState>();
// final _addAccountNavigatorKey = GlobalKey<NavigatorState>();

class MyRouter{
  static final router = GoRouter(
    navigatorKey: _navigatorKey,
    initialLocation: "/accounts_page",
    routes: [
      GoRoute(
          name: "accounts_page",
          path: "/accounts_page",
          builder: (context, state) => const MyHomePage(),
          routes: <RouteBase>[
            GoRoute(
              name: "account_info_step",
              path: "account_info_step",
              builder: (context, state) => const TestPage(),
            ),
            GoRoute(
              name: "account_type_step",
              path: "account_type_step",
              builder: (context, state) => const TestPage(),
            ),
            GoRoute(
              name: "account_detail_step",
              path: "account_detail_step",
              builder: (context, state) => const TestPage(),
            ),
          ]
      ),
    ],
  );
}

I think this is what you are looking for. Also, note that you don't need to add a '/' in path for nested screens. And to navigate to those nested screens, you can do something


like this:-

context.go('/accounts_page/account_info_step');

edit: I've understood your requirement, and I think this will help. In your code only,

GoRoute(
              name: "account_type_step",
              path: "account_type_step",
              builder: (context, state) => const TestPage(),
            ),

let’s say you don’t want the bottom nav bar in this screen, there is a parameter called parentNavigatorKey. You can set it with you rootNavigator Key _navigatorKey.

GoRoute(
          parentNavigatorKey: _navigatorKey,
          name: "account_type_step",
          path: "account_type_step",
          builder: (context, state) => const TestPage(),  
),
Rapt answered 18/2, 2023 at 11:19 Comment(7)
I can confirm, what I was trying to do wasn't right. Thanks for your answer, but my question is: how to wrap the steps in a widget, as you can do with a ShellRoute?Ancona
I'm really sorry, I'm not sure if I follow you correctly. Do you mean creating the GoRoute inside the add_account_page?Rapt
No worries! What I was trying to achieve with go_router is to navigate between screens inside a page (like a PageView): I have a button at the bottom of my screen, that doesn't move and allows me to go from one step to the next one. But it feels like it's not possible with go_router apparently...Ancona
You mean like the bottom navigation bar that stays persistent and only the screen above changes? If that is what you want, it can be accomplished with ShellRoute, I can help you with it !!Rapt
Thank you! Yes, I know I can do that with ShellRoute, but I need my bottom navigation bar to be in only one page and not by default in my entire app. That's why I eventually chose to go with the PageView.Ancona
Thats also possible, I can help you with that. I have updated my Answer, Maybe that could help you.Rapt
OK thanks! It actually feels a bit weird to "disable" the nav bar for the other pages, but I get the idea.Ancona
A
0

If your intention is to get to AccountInfoStep() full path leading to this builder should be added in your case:

context.push("/accounts_page/account_info_step")

I assume you are missing name for your top routes to represent proper nesting to use the context.pushNamed()

Alasteir answered 17/2, 2023 at 15:27 Comment(1)
Thanks but I get the following error: no routes for location: /accounts_page/account_info_step. I guess it should be add_account_page instead of accounts_page, but I don't know how to name the ShellRoute, if it's possible...Ancona

© 2022 - 2024 — McMap. All rights reserved.