How to Keep BottomNavBar persist between screens in Flutter

canisterism
Flutter Community
Published in
4 min readFeb 24, 2020

Introduction

When you create an app with Flutter, you have to do “routing” in most cases. It’s so easy to create routings with Flutter and BottomNavigationBar, however, I was stacked about some routing and layout stuff.

Today I’ll explain how to keep your BottomNavBar persist even you move back and forth.

The code I use in this article is here:

https://github.com/canisterism/flutter_bottom_navbar/

What is the Problem?

One day, I created a layout with BottomNavigationBar. But I realized that BottomNavBar is gone when you Navigator.of(context).push().

I want to keep this BottomNavBar on screen, even after a move to the next screen. For inpatient readers, I’ll explain briefly first how to make my wish come true.

Tl:dr; How to keep BottomNavBar?

Use Cupertino widgets.

This is ios-flavored widgets. You can keep BottomNavBar on the screen with this.

https://gph.is/2i84mE5

I’m showing below how to implement persist BottomNavBar with Cupertino widgets. Just scroll to the bottom of this article, if you immediately want to check it.

Why BottomNavBar is gone?

In this section, I’ll explain what’s going on while BottomNavBar vanishes.

How Navigator and routing works in Flutter

(Apologies: I simplified mechanism here for easy to understand, so some detail might be inaccurate. But any suggestion welcomed!)

In Flutter, Navigator is responsible for routing.

https://api.flutter.dev/flutter/widgets/Navigator-class.html

When you push with Navigator.push() orNavigator.pushNamed(), flutter is trying to find the nearest Navigator. If Flutter finds Navigator, it would try to rebuild(render) specified widgets (in most cases, they are screen), from the Navigator as the starting point.

What’s going on with normal BottomNavigationBar

With just use normal BottomNavigationBar, a Simplified widget tree is like below.

▼ MyApp
▼ MaterialApp
▼ <some other widgets>
▼ Navigator
▼ <some other widgets>
▼ App
▼ Scaffold
▼ body: <some other widgets>
▼ BottomNavigationBar
...

The nearest Navigator would be the root one. But with CupertinoTab widgets, BottomBarItems have their own Navigator, like below.

▼ MyApp
▼ MaterialApp
▼ <some other widgets>
▼ Navigator
▼ <some other widgets>
▼ App
▼ Scaffold
▼ body: <some other widgets>
▼ BottomNavigationBar
▼ Navigator
...
▼ Navigator
...

Therefore, Flutter can find these under Navigators, not the root one. So with CupertinoTab widgets, you can keep BottomNavBar even after you move to another screen.

How to implement

I’ve explained how BottomNavBar works. Next, I’ll show you how to implement it. Here’s code.

Tada!🎉 Now you keep the BottomNavBar between page transitions! And this app is keeping each page state because BottomNavBar has state.

Conclusion

I’ve explained how to keep BottomNavBar between transition above.

Standard Flutter BottomNavBar widgets seem they don’t support keeping it between the screens.

In the link of codelab below, it mentions the Cupertino tab.

https://codelabs.developers.google.com/codelabs/flutter-cupertino/#3

Cupertino tab. has a separate scaffold because on iOS, the bottom tab is commonly persistent above nested routes rather than inside pages.

It says Cupertino tab is persisted because it’s iOS flavored, but Material Design also says:

When used, the bottom navigation bar appears at the bottom of every screen.

😕…

I’m not sure what on earth this contradiction is.

Any comment is welcomed. Thanks!

Extract Tips: CupertinoTab widgets Make Easy

In this section, I’ll explain about Cupertino widgets I used in this article. You can understand the overview of CupertinoTab widgets here, but you might want to look up official docs and another article if you want to understand detail.

CupertinoTabScaffold

A widget scaffolding app structure that has fixed BottomNavBar. The example above, I didn’t write any onTap callback to detect which tabBarItem tapped, because this widget listens to when and which CupertinoTabBar tapped. You write the tab content in tabBar:, screens you want to show in tabBuilder:

CupertinoTabBar

A widget shows BottomNavBar which has BottomNavigationBarItem as its children.

CupertinoTabView

A widget that has one screen to show and Navigator. Notice importance that CupertinoTabView has Navigator. This enables an app to have each page's state, even pages, and tabs transition.

CupertinoPageScaffold

A widget scaffolding iOS flavored app structure.

CupertinoNavigationBar

A widget used for navigationBar: of CupertinoPageScaffold. You can set Icon and etc.. in its leading:

See also

--

--

canisterism
Flutter Community

A web developer in Tokyo. Usually use Flutter, React, Vue, Elm and Rails.