Mastering Navigation in Flutter
Every app needs to navigate between pages, and Flutter does this using the Navigator
widget.
How Navigation works?
The fundamental concept of navigation is the “stack”. You can think of it like a stack of cards. The current page you are looking at is the card on the very top. There are two ways you can change which card you are looking at and that is by adding one on top (known as “pushing” it on top), or by removing the top card (“popping” it off the top).
We will walk through a visual example that has three screens in total.
- Home Screen
- Second Screen
- Third Screen
In the diagram below you can see the current state of the app, and what the stack looks like at that state.
Push
Like in the card example let’s say we want our app to navigate to a different screen called “Second Screen”. We would want to push
it onto the top of the stack of pages.
Once this is executed, the current application and stack will look like this.
If we follow the same process and navigate to a third screen our application and stack will look like this.
Pop
To go back and see the previous “Second Screen” you would need to “pop” the topmost layer off of the current stack.
This will result in the stack being 2 pages deep, and you can see the “Second Screen” again.
Basic Navigation
Push
That is the main concept of navigation within an application. To use it within your Flutter app, your code will look like this:
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const SecondPage())
);
You will use the Navigator
widget of the current context, and call the push
method. This will add a new layer to the stack.
That navigation “stack” that we were talking about is actually a stack of Route
objects. These routes are the actual pathways to get to the specific screen. A Route
can have some extra behaviors and properties. For example, you can define what type of animation will be used when bringing in the new page.
MaterialPageRoute
In the code above we use a MaterialPageRoute
which is a platform-specific Route
. What does that mean?
It will check what platform you are running (e.g. iOS, Android), and perform the platform-specific animations for transitioning between pages.
For Android, it zooms and fades, while for iOS it slides in from the right side.
Pop
To go back to the previous screen, the code will look like this:
Navigator.of(context).pop();
Named Navigation
If you’re coming from web development, you will probably be familiar with routes. In the URL of the website, you can see the route for the different pages. For example, this page is on the /navigation
route within the /flutter
route.
You can assign these names within Flutter and maneuver throughout your application using them.
Warning
Flutter actually doesn’t recommend you to use named routes because the behavior of deep links can’t be customized, and the forward button doesn’t work. For a solution with all this, you should use Navigator 2.0
When using named navigation, instead of defining the route on the fly, you do it ahead of time. These routes need to be configured within the MaterialApp
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => const HomeScreen(),
'/second': (context) => const SecondScreen(),
},
)
The initial route on any website or app is '/'
. You can customize this in Flutter to something else, but we will keep it '/'
.
Within the routes
, we define all our routes. So the '/'
route will lead us to our Home Screen, where our app will start, and we will predefine a '/second'
route which we will be able to use to navigate to the second screen.
Where is Hungrimind home route?
Depending when you read this, you might notice
hungrimind.com
always redirects to/flutter
. Eventually there will be a home page on the'/'
route, but for now everything gets directed to/flutter
.
Push
Using named routes allows your syntax to be a little cleaner since your routes were already defined.
Navigator.of(context).pushNamed('/second');
Pop
The logic is the same for popping as before, since don’t have to define the specific route. We just remove the very top layer.
Navigator.of(context).pop();