Navigation and Its Styles
Learn to switch between different screens.
We'll cover the following
Overview
Navigation is a core concept in mobile app development. It is how users move from one screen to another. Well-handled navigation keeps an app organized and enhances its functionality.
Routing is the process of defining navigation elements and the corresponding page. We can think of the screens or pages as routes.
Navigation stack
When handling navigation, flutter implements the stack concept: Last In, First Out (LIFO). The last page pushed to the stack is visible to the user and is the first page to be popped off the stack. Here is an illustration of the navigation stack:
Managing the navigation stack
In Flutter, we can handle navigation using two styles:
- Imperative navigation
- Declarative navigation
Imperative navigation
Navigator 1.0 is the standard reference to imperative navigation. It uses the Navigator
widget as the routing mechanism.
In imperative navigation, we can only add a page to the top of the navigation stack and remove the top route. Routes are pushed into or popped off the navigation stack using named or anonymous routes.
The most common APIs include:
push()
: It adds a new route to the top of the stack.pop()
: It removes the top route from the stack.
Navigator 1.0 is simple and easy to use. However, it has some limitations. The following are the disadvantages of imperative navigation:
- It’s difficult to push or pop multiple pages on the stack.
- It’s difficult to add or remove a page underneath the top page of the stack.
- It’s hard to manage and scale.
- The Android system back button might not work when you have nested navigation.
Working with declarative navigation solves these drawbacks.
Declarative navigation
Navigator 2.0 is the standard reference to declarative navigation and does not replace Navigator 1.0 because we can use them together. It uses the Router
widget as the routing mechanism.
This navigation style allows us to take complete control of the navigation stack.
To understand Navigator 2.0, we need to know the following concepts:
Page
: It is an abstract class used to set the navigation stack history.Router
: It configures the list of pages that Navigator 2.0 is supposed to open and close.RouteInformationParser
: It translates route information fromRouteInformationProvider
into user-defined data type and translates user-defined data type to route information.RouteInformationProvider
: It provides route information.RouterDelegate
: It listens toRouteInformationParser
and the app state to build and configure the navigating widgets.BackButtonDispatcher
: It reports the system back button presses toRouter
.TransitionDelegate
: It decides how pages transition in and out of the screen.
Below is an illustration of the above-mentioned concepts from the Flutter team:
Navigator 2.0 already seems complex compared to Navigator 1.0. Why use it, then? The following are the advantages of declarative navigation:
- We have more control of the navigation stack.
- It works better with the Android system back button.
- We can use both imperative and declarative navigation in the same app.
- It allows us to handle web URLs and deep linking.
- And many more!
So, how do we know when to use imperative or declarative navigation?
- If we’re working on small apps for demos, we go the imperative way.
- If we’re working on a large complex app, we go the declarative way.
In the following lessons, we’ll use the imperative and declarative navigation style to navigate through the shop app as shown below: