Tabs with independent navigation stacks in Flutter with app_state package

Alexey Inkin
Flutter Senior
Published in
3 min readApr 3, 2022

This is a part of the series on app_state package. The beginning is here.

In the previous part, we set up navigation and web support with URLs. Now let’s do multiple tabs with independent navigation stacks in each of them. In addition to the book list, we will have another tab:

When we switch to it and back, the stack in the first tab is preserved for us.

Take a look at the example project found here. This is the structure with new files highlighted:

Let’s walk through what has changed from the previous part.

PageStacksBloc

The project has changed its heart. Instead of PageStackBloc we now use PageStacksBloc. It contains multiple page stacks with each having a string key. It also may consider one of them current.

Each stack has its own bottom page that is always there. Each stack uses the same page factory which will potentially allow any page to show on any stack. This is the key to Instagram-like navigation where a profile may show on the Likes tab, or on the Explore tab, or any other one. But we are not going to play with this.

Also note that we changed the back button dispatcher class to work with this bloc.

PageStacksRouterDelegate

The router delegate has changed. Previously, we were using PageStackRouterDelegate that took care of building the Navigator widget and updating it on some page events. Now we use the new class MaterialPageStacksRouterDelegate (note the “s”). It still takes care of updating on events, but it has no idea how we want to present the stacks. Tabs are common, but we may also want to run split-screen, so no common solution here. So it must be given a home screen.

HomeScreen

In the home screen, we listen to events in PageStacksBloc to rebuild. We may create any arrangement of the stack, but we will go with tabs with bottom navigation buttons:

Here we are using KeyedStack and KeyedBottomNavigationBar widgets. These are convenient alternatives to IndexedStack and BottomNavigationBar provided by keyed_collection_widgets package. They abstract the indexes so we do not have to convert indexes to stack keys and vice versa. There is however a minor inconvenience that we use TabEnum for tabs and String for stack keys. But this conversion is much more straightforward than with int.

Push pages

We can push a page to the current page stack like this:

This will also help to mimic Instagram. Call this in any reusable widget, like a profile picture, and the new screen will show in that current tab.

PageStacksRouteInformationParser

We used to extend PageStackRouteInformationParser to parse URLs into a stack configuration. Now we extend PageStacksRouteInformationParser (note the “s”).

The difference is that the latter recovers state for all stacks.

Provide default stack to PagePath objects

When URL is typed in, it is converted to PagePath object which is used to create stacks of pages. With single stack, each path was populating that one stack. With multiple stacks, each path must know what tab should be active if it was the entry point to the app. Otherwise an exception is thrown.

For this, override defaultStackKey getter in each PagePath:

And we are good to go. You may run the app to see how tabs switch.

In Android, the back button always closes the current screen and does not lead to the previously selected tab. However, in browser, the back button will take you to a previously selected tab as this is how browsers are supposed to work. Traditionally their back-forward navigation has to do with history and not with hierarchy.

In the next tutorial, we will add a modal dialog and wait for its result. This has significant perks with app_state.

--

--

Flutter Senior
Flutter Senior

Published in Flutter Senior

A knowledge base to my company. We use this to teach juniors and link here in reviews. And so can you. Everything is heavily opinionated here except that Flutter and the related logo are trademarks of Google LLC. We are not endorsed by or affiliated with Google LLC.

Alexey Inkin
Alexey Inkin

Written by Alexey Inkin

Flutter GDE & Team Leader, IEEE Senior Member, Software PM, Career mentoring. EB-1A Extraordinary ability immigrant. 20 years in pro software development.

No responses yet