In this article, we’ll explore how to build a multi-screen application in Flutter using Navigation and pass data between screens through routes.

Until this article in the basic Flutter series, we’ve mainly focused on single-screen apps. If you are eagerly waiting to build a multi-screen application, this article is for you!  We’ll see how to add multiscreen to your application and transition between them.

It also explains how to pass data between widgets. Let’s explore this subject in detail!

Guidance from App Demo

Below is an overview of the sample application to create:

As you know, this application has two screens and let’s see how we can build it if we want to pass data from this screen to another!

Below is the snapshot code for the first screen used in this application. Write another widget to a separate file (first_screen.dart) and import it into the main.dart file later. This can reduce the amount of code, facilitate maintenance, and optimize performance

You can see that FirstScreen is a stateless widget. In the overview, there is a Scaffold with an appBar and a Body section. The Body section contains a column widget (where the widget displays the view in a column), and the child widgets of the column are SizedBox, Text, and ElevatedButton, respectively. When you click the Raised Button, the navigator transitions the second screen to the top of the first screen with the identifier name of the second screen. More on this later.

To let Flutter recognize the screen you want to navigate to, transition through the name of the screen. So where you declare that you want to use this screen second_screen you need to import the .dart.

Note: Each screen you need to navigate (each scaffold widget is considered a separate screen) must have a unique identifier. Here we have defined routeName as static const on both screens.

The second screen  

The second screen, declared in another second_screen.dart, contains the following code:

The code structure of this widget is basically the same as the first screen, but one button is added. Here we import the first_screen.dart so that we can navigate the screens we need to navigate with the routeName constant. The second button is a TextButton. The FlatButton is used to transition to the first screen with the pop() method. The pop() method simply removes the widget/top screen from the stack. We will talk about this in more detail.

main.darrt file

The navigation setup is not yet complete. Also, the main.dart file must register the root of all screens found in MaterialAppWidget.

You can see that you have imported both first_screen .dart and second_screen.dart widgets into the main.dart file. The default root page: FirstScreen() is used as the initialwidget/screen when the app is launched.

I’ve also noticed that I’ve mentioned top-level routes in my application. For multiscreen, you need to register all the scones here.

Why you need to declare routes like the one above?

The behavior of Navigator in Flutter is like searching for a named route name in a map of many corresponding routes.

If the name is valid, builder(){…} The methods are concatenated. In other words, use the WidgetBuilder to create a MaterialPageRoute that performs screen navigation operations in your Flutter app.

Why use static const for route name?

You can only use route name by declaring the name directly in the route table outside of your app, and then using that value to navigate around. However, if you need to update the route name, you must change the route name everywhere you used it.

Also, typos during use in navigation can cause unexpected errors and make tracking difficult. So, we will use the static constant that we want to use for a single variable.

From now on, the actual route name value is in the widget and can be changed whenever it needs to be changed in many places. This is a simpler approach to assign and use route name.

Use parameters to pass data between routes.

Route can pass data from this screen/widget to another screen/widget. See the following example: There is a list of recipes, and clicking on recipes will take you to another screen that displays the recipe details of the detailed recipes.

In the recipe details screen, you need to know the ID (recipe_id) of which recipe selected so that you can get the corresponding data from the backend/server. So, to get the recipe_id from the recipe list screen, write:

Here you can see that we are using recipeId as a parameter for route. Now, on the second screen, if you need this recipe_id, you can extract the data from the parameters of route as follows:

Finally, the data from the previous screen is displayed on the current screen. This is a very basic example to understand dataflow.