Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: Keep BottomNavigationBar When Push to New Screen with Navigator

In iOS, we have a UITabBarController which stays permanently at the bottom of the screen when we push to a new ViewController.

In Flutter, we have a bottomNavigationBar of a Scaffold. However, unlike iOS, when we Navigator.push to a new screen, this bottomNavigationBar disappears.

In my app, I want to fulfil this requirement: Home screen has a bottomNavigationBar with 2 items (a & b) presenting screen A & B. By default, screen A is displayed. Inside screen A, there is a button. Tap that button, Navigator.push to screen C. Now in screen C, we can still see the bottomNavigationBar. Tap item b, I go to screen B. Now in screen B, tap item a in the bottomNavigationBar, I go back to screen C (not A, A is currently below C in the navigation hierarchy).

How can I do this? Thanks, guys.

Edit: I'm including some pictures for demonstration:

Screen A Screen A

Tap Go to C button, push to screen C Screen C

Tap Right item inside bottom navigation bar, go to screen B Screen B

like image 510
kcatstack Avatar asked Apr 03 '18 11:04

kcatstack


People also ask

How do you set up the same bottom navigation bar for all screens in Flutter?

You can use IndexedStack to persist State when you change the page. persistent_bottom_nav_bar manage the Navigation stack of individual tabs and using this library you can manage hide/show BottomNavigationBar.

How do I use BottomNavigationBar Flutter?

A bottom navigation bar is a material widget that is present at the bottom of an app for selecting or navigating to different pages of the app. It is usually used in conjunction with a Scaffold, where it is provided as the Scaffold. bottomNavigationBar argument.


2 Answers

tl;dr: Use CupertinoTabBar with CupertinoTabScaffold

The problem is not in Flutter but in UX just like Rémi Rousselet has mentioned.

It turned out Material Design doesn't recommend sub-pages in the hierarchy to access the Bottom navigation bar.

However, iOS Human Interface Guide recommend this. So, to use this feature, I had to adapt Cupertino widgets instead of Material ones. Specifically, in main, return a WidgetsApp/MaterialApp which contains a CupertinoTabScaffold. Implement the tab bar with a CupertinoTabBar and each screen is a CupertinoTabView.

like image 58
kcatstack Avatar answered Sep 21 '22 09:09

kcatstack


Screenshot:

enter image description here


Starting point:

void main() => runApp(MaterialApp(home: HomePage())); 

HomePage [BottomNavigationBar + Page1]

class HomePage extends StatelessWidget {   @override   Widget build(BuildContext context) {     return Scaffold(       bottomNavigationBar: BottomNavigationBar(         backgroundColor: Colors.orange,         items: [           BottomNavigationBarItem(icon: Icon(Icons.call), label: 'Call'),           BottomNavigationBarItem(icon: Icon(Icons.message), label: 'Message'),         ],       ),       body: Navigator(         onGenerateRoute: (settings) {           Widget page = Page1();           if (settings.name == 'page2') page = Page2();           return MaterialPageRoute(builder: (_) => page);         },       ),     );   } } 

1st Page:

class Page1 extends StatelessWidget {   @override   Widget build(BuildContext context) {     return Scaffold(       appBar: AppBar(title: Text('Page1')),       body: Center(         child: RaisedButton(           onPressed: () => Navigator.pushNamed(context, 'page2'),           child: Text('Go to Page2'),         ),       ),     );   } } 

2nd Page:

class Page2 extends StatelessWidget {   @override   Widget build(BuildContext context) => Scaffold(appBar: AppBar(title: Text('Page2'))); } 
like image 35
CopsOnRoad Avatar answered Sep 21 '22 09:09

CopsOnRoad