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
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.
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.
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
.
Screenshot:
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'))); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With