Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter persistent navigation bar with named routes?

Tags:

flutter

dart

I've been searching around for a good navigation/router example for Flutter but I have not managed to find one.

What I want to achieve is very simple:

  1. Persistent bottom navigation bar that highlights the current top level route
  2. Named routes so I can navigate to any route from anywhere inside the app
  3. Navigator.pop should always take me to the previous view I was in

The official Flutter demo for BottomNavigationBar achieves 1 but back button and routing dont't work. Same problem with PageView and TabView. There are many other tutorials that achieve 2 and 3 by implementing MaterialApp routes but none of them seem to have a persistent navigation bar.

Are there any examples of a navigation system that would satisfy all these requirements?

like image 515
Janne Annala Avatar asked Apr 05 '18 20:04

Janne Annala


People also ask

Can flutter routes be named?

The solution is to define a named route, and use the named route for navigation. To work with named routes, use the Navigator.

How do you use the common bottom navigation bar in 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

All of your 3 requirements can be achieved by using a custom Navigator.

The Flutter team did a video on this, and the article they followed is here: https://medium.com/flutter/getting-to-the-bottom-of-navigation-in-flutter-b3e440b9386

Basically, you will need to wrap the body of your Scaffold in a custom Navigator:

class _MainScreenState extends State<MainScreen> {   final _navigatorKey = GlobalKey<NavigatorState>();    // ...    @override   Widget build(BuildContext context) {     return Scaffold(       body: Navigator(         key: _navigatorKey,         initialRoute: '/',         onGenerateRoute: (RouteSettings settings) {           WidgetBuilder builder;           // Manage your route names here           switch (settings.name) {             case '/':               builder = (BuildContext context) => HomePage();               break;             case '/page1':               builder = (BuildContext context) => Page1();               break;             case '/page2':               builder = (BuildContext context) => Page2();               break;             default:               throw Exception('Invalid route: ${settings.name}');           }           // You can also return a PageRouteBuilder and           // define custom transitions between pages           return MaterialPageRoute(             builder: builder,             settings: settings,           );         },       ),       bottomNavigationBar: _yourBottomNavigationBar,     );   } } 

Within your bottom navigation bar, to navigate to a new screen in the new custom Navigator, you just have to call this:

_navigatorKey.currentState.pushNamed('/yourRouteName'); 

To achieve the 3rd requirement, which is Navigator.pop taking you to the previous view, you will need to wrap the custom Navigator with a WillPopScope:

@override Widget build(BuildContext context) {   return Scaffold(     body: WillPopScope(       onWillPop: () async {         if (_navigatorKey.currentState.canPop()) {           _navigatorKey.currentState.pop();           return false;         }         return true;       },       child: Navigator(         // ...       ),     ),     bottomNavigationBar: _yourBottomNavigationBar,   ); } 

And that should be it! No need to manually handle pop or manage a custom history list.

like image 157
CZX Avatar answered Sep 17 '22 14:09

CZX


CupertinoTabBar behave exactly same as you described, but in iOS style. It can be used in MaterialApps however.

Sample Code

like image 40
Kyaw Tun Avatar answered Sep 20 '22 14:09

Kyaw Tun