Flutter Navigator 2.0 and Deep Links
With Flutter’s Navigator 2.0, learn how to handle deep links in Flutter and gain the ultimate navigation control for your app. By Kevin D Moore.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Flutter Navigator 2.0 and Deep Links
40 mins
- Getting Started
- Navigator 1.0
- Navigator 2.0
- Pages Overview
- Login Page
- Create Account Page
- Shopping List Page
- Details Page
- Cart Page
- Checkout Page
- Settings Page
- Pages Setup
- AppState
- RouterDelegate
- Implementing build
- Removing Pages
- Creating and Adding a Page
- Modifying the Contents
- RouteInformationParser
- Root Widget and Router
- Navigating Between Pages
- Splash Page Navigation
- BackButtonDispatcher
- Deep Linking
- Parse Deep Link URI
- Testing Android URIs
- Where to Go From Here?
Flutter’s first stable release was in December 2018, and it has grown rapidly since then. As is the case with any software, the developers who built it or use it are constantly refining it with each new version.
Initially, navigation between pages in Flutter was possible with Navigator 1.0 only, which could push
and pop
pages. Most use cases required basic navigation that wasn’t a problem for Navigator 1.0. But with the introduction of more complex navigation use cases — especially after Flutter for Web came out — developers wanted the ability to add multiple pages in one go or remove any offscreen page(s) on the onscreen page. To cover these use cases, the Flutter team introduced Navigator 2.0.
In this tutorial, you’ll learn how to use Navigator 2.0 by building pages of a shopping app brilliantly called, Navigation App :]. You’ll also learn how it can provide much more granular control for your app’s navigation and deep linking. To do so, you’ll learn how to implement:
- RouterDelegate
- RouteInformationParser
- BackButtonDispatcher
This tutorial uses Android Studio, but Visual Studio Code or IntelliJ IDEA will work fine as well.
Getting Started
Download the starter project by clicking the Download Materials button at the top or bottom of the page.
The starter app is a set of screens for the shopping app. The UI doesn’t do much, but it shows how to navigate between pages. This set of pages — represented as screens — is in the image below:
The app starts with the Splash page, which shows an image:
Run your app and verify it opens to this page. The app will stay on this page since the navigation system isn’t yet implemented. Gradually, you’ll add code to navigate between all screens.
Once you implement the navigation, the app should display the Splash page for a short duration and then show the Login page if the user isn’t logged in. If they are, they’ll see the Shopping List page instead. This logged-in state is saved as a Boolean
value in the app’s local storage using the shared_preferences package.
The user can go to the Create Account page for signing up or stay on the Login page, where they can log in and then navigate to the Shopping List page.
Note that this tutorial won’t cover the implementation of a functional login system or any real-world shopping app features. The screens and their corresponding code mimic their UI to explain the navigation concept.
Navigator 1.0
Navigator 1.0 uses the Navigator
and Route
classes to navigate between pages. If you want to add, or push
, a page, use:
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return MyNewScreen();
}),
);
Here, MaterialPageRoute
returns an instance of your new screen, i.e. MyNewScreen
.
To remove, or pop
, the current page, use:
Navigator.pop(context);
These operations are straightforward, but things get interesting if you have a use case that requires recreating a set of pages, such as for deep linking.
In the context of mobile apps, deep linking consists of using a uniform resource identifier (URI) that links to a specific location within a mobile app rather than launching the app.
For example, while building an e-commerce app, you may want the user to go to a product page when they tap the “Product X is now on Sale!” notification. To handle this, the app needs to clear the current navigation stack of the app, add the home screen that displays products in a list and then add the product page to this stack of pages. With Navigator 1.0, this is difficult.
Luckily, Navigator 2.0 provides a lot more flexibility for such a use case.
Navigator 2.0
Unlike Navigator 1.0, which uses an imperative style of programming, Navigator 2.0 uses a declarative style. As a result, it feels more “Flutter-like”. Understanding Navigator 2.0 involves understanding a few of its concepts such as:
- Page: An abstract class that describes the configuration of a route
- Router: A class that manages opening and closing pages of an application
-
RouteInformationParser: An abstract class used by the
Router
‘s widget to parse route information into a configuration -
RouteInformationProvider: An abstract class that provides route information for the
Router
‘s widget -
RouterDelegate: An abstract class used by the
Router
‘s widget to build and configure a navigating widget -
BackButtonDispatcher: Reports to a
Router
when the user taps the back button on platforms that support back buttons (such as Android) - TransitionDelegate: The delegate that decides how pages transition in or out of the screen when it’s added or removed.
This article doesn’t cover TransitionDelegate
, as in most use cases, DefaultTransitionDelegate
does a good job with transitions. If you need to handle transitions between pages in a unique way, you can create your own delegate by extending TransitionDelegate
.
Here’s a visual representation of the concepts mentioned above:
The classes in gray are optional to implement when using Navigator 2.0. However, the ones in blue, i.e. RouteInformationParser
and RouterDelegate
, must be implemented to use Navigator 2.0. You’ll learn about both of these, and the optional BackButtonDispatcher
, in the sections below.
Pages Overview
Before you begin to implement any navigation, the next sections will provide an overview of the pages in your starter app.
Login Page
The Login page is the first page to appear after the Splash page if the user hasn’t already logged in:
Clicking on the Create Account button takes the user to the Create Account page, and pressing the Login button takes the user to the Shopping List page. When pressing the Login button, set the logged-in
flag using Shared Preferences to true
so that the next time the user logs in, they go straight to the Shopping List page after the Splash page.