How To Navigate Between Pages In Your Flutter Application

Introduction Link to heading

In this article, we are going to implement navigation logic and learn how to navigate between pages in your Flutter application. Create multi-page apps without any effort!

If you don’t want to develop a single-page application, you will need a navigation pattern to get from one page to another. In a Flutter application, there are 3 different ways to handle this problem. I’ll show them to you in the following sections. Let’s see how to navigate between pages in your Flutter application!

Example app navigation between pages

Example app navigation between pages

The Navigator object Link to heading

The Navigator object exposes methods to transition from one page to another within a Flutter application. It behaves like a stack data structure which means that the last element added will be the first element removed. To access the Navigator you can call Navigator.of(context) where context represents the current BuildContext. I’ll demonstrate it in the next sections.

The basic way — push and pop Link to heading

The Navigator behaves like a stack, so the most simple way is to push a new page onto it when you want to navigate to it and to pop a page if you want to go back. The following code demonstrates how to navigate to a new page.

To go back, you simply call Navigator.of(context).pop() and you’re back at the previous page. To check if back navigation is possible, there is the method canPop() which returns false if there aren’t any more pages on the stack to be popped. The hardware or software back button of your mobile device will also trigger the pop() method if possible.

Warning

If you call pop() and there is only the current page on the stack, the application will be closed.

To skip the page history entirely, you can also use the pushReplacement() method. It will replace the current page with the given one so that there is only the given page on the stack. But the user won’t be able to use the back button.

The diagram shows the stack behavior once again:

The advanced way — predefined routes Link to heading

Predefined routes are a good choice if you have a smaller amount of pages that don’t require any arguments to be passed in. To configure the routes, you need to fill the routes property in the MaterialApp object. A simple example is below:

In this case, you need to use the pushNamed() or pushReplacementNamed() methods of the Navigator object. So for example when navigating to the login page which has a predefined route /login, you call Navigator.of(context).pushNamed(”/login”). It is recommended to define constants for the routes to reduce possible spelling errors.

Warning

Don’t forget the initialRoute property or add an onUnknownRoute handler. Otherwise, the app won’t start.

The expert way — route generation Link to heading

If you don’t use the routes table, but want to go with named routes, you can add a handler to the onGenerateRoute function in the MaterialApp object. You can see an example of that below:

Every time when a route is pushed via the Navigator, this handler function is executed to find the correct page to navigate to. The name property contains the passed route. The big advantage is that you can handle navigation arguments with this approach. They are passed via the arguments property. It gives you more control than the static approach with predefined route tables.

Sending data to another page Link to heading

Passing data to a page is pretty simple. When using the push-pop approach without named routes, you just need to add the data as a constructor argument.

Dart

Navigator.of(context).push(MaterialPageRoute(builder: (context) => Login(data: "dummy")));

When using named routes approach, you can use the arguments parameter of the pushNamed method to pass any data you want.

Dart

Navigator.of(context).pushNamed(”/login”, “dummy”);

The parameter is of the type Object, so you can pass anything you want from simple strings over maps to custom objects. The target page is responsible for parsing or casting the data. Have a look at the paragraph about route generation above. If you are using a predefined routes table, you cannot pass any data at runtime.

The pop() method can also pass data. Therefore, the caller needs to wait for the back navigation and read the passed information. Just call Navigator.of(context).pop(”dummy”); to pass a string to the caller. The caller should await the return of the data.

Dart

var res = await Navigator.of(context).pushNamed("/login"); // <-- wait for pop()
print(res as string); // prints "dummy"

Further reading Link to heading

If you want to know more details about navigation in Flutter, check the following links.

Google uses cookies to deliver its services, to personalize ads, and to analyze traffic. You can adjust your privacy controls anytime in your Google settings. Learn more.

Learning Flutter’s new Navigation and Routing system Link to heading

This article explains how Flutter’s new Navigator and Router API works. If you follow Flutter’s open design docs, you might have seen…

Conclusion Link to heading

In this article, we had a look at navigation in a Flutter application and learned how to navigate between pages in your Flutter application. Either with push and pop, with named routes, or with dynamic route generation, there are many possible ways for this task.

You can find the source code on GitHub.

How to host your Flutter web app with Firebase Hosting Link to heading

It is very simple to host your existing Flutter web app with Firebase Hosting. This article guides you through all the steps needed.

Boost your Flutter apps to the max with these 6 performance tips Link to heading

Get smoother scrolling and animations, less memory consumption, and more execution speed with these performance tips for Flutter apps.

The Flutter pubspec.yaml in detail Link to heading

The pubspec.yaml file is the main configuration file for your Flutter app. In this article, we’ll have a look at its contents.