Flutter: Advance Routing and Navigator (Part 2)

Nitish Kumar Singh
6 min readMay 30, 2019

This Article is having two parts and this is second part.

In this article, we will understand the implementation of data sharing while routing. There is three different way of doing that. I will discuss them one by one.

Sharing of data is very much important when we are moving from one to another screen. We see the medium article and we click on the author name we move to the author profile. How the profile pages know that for which author you have requested? These all are done using the data which is being shared while moving to the other page. There could be data or some object whatever you want to share you can share in a flutter application.

Example 1 : Simple Routing

This is one of the simplest ways of routing. Whenever anyone first learns about the routing and data sharing, they learn this particular approach.

You can share any kind of data i.e. String, integer, Map, List, Object, etc. In this example, we will share an object from one screen to the other screen.

import 'package:flutter/material.dart';

void main() {
runApp(MaterialApp(
home: HomePage(),
));
}

class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: Center(
child: RaisedButton(
onPressed: () {
User user = new User(name: 'Nitish', age: 18);
Route route =
MaterialPageRoute(builder: (context) => SecondHome(user: user));

Navigator.push(context, route);
},
child: Text('Second Home'),
),
),
);
}
}

class SecondHome extends StatelessWidget {
final User user;

SecondHome({this.user});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('${this.user.name} - ${this.user.age}'),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go Back'),
),
),
);
}
}

class User {
final String name;
final int age;

User({this.name, this.age});
}
  • User Class we have created the user class and we will pass the user object to the next page/screen
  • SecondHome(user : user) we are passing the user object to the next page/screen
  • SecondHome({this.user}) we are initializing the user object here which is coming from the previous page/screen.

I don’t think this example need more explanation.

Example 2 : Named Routing

This is named route and I discussed this in the previous post. So I will only focus on the things which are new here.

In the last example, we had passed the data in Constructor but here we don’t have direct/indirect access to the Constructor of the SecondScreen. So, we need to do something else.

routes: <String, WidgetBuilder>{
'/home': (context) => HomePage(),
'/second': (context) => SecondHome(),
},
  • This is how we defined routes
Navigator.pushNamed(context, '/second', arguments: user)
  • In order to move to the next page, we have to tell the name of the routes. There is an optional argument in the pushNamed and that is called arguments. arguments accepts the Object. We can pass any kind of object here.
  • Now we have passed the data to the next screen.
RouteSettings settings = ModalRoute.of(context).settings;
  • To access the data on our next screen we will need RouteSettings.
  • Whenever we use the routes in our application the then we get RouteSettings.
  • RouteSettings gives us access to the name of the route and parameter which is being passed to the routes.

Using RouteSettings we are getting the data which is being passed from the previous screen. Let’s see the full source code.

Full Source Code

import 'package:flutter/material.dart';

void main() {
runApp(MaterialApp(
initialRoute: '/',
routes: <String, WidgetBuilder>{
'/': (context) => HomePage(),
'/second': (context) => SecondHome(),
},
));
}

class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: new Center(
child: RaisedButton(
onPressed: () {
User user = new User(name: 'Nitish', age: 18);
Navigator.pushNamed(context, '/second', arguments: user);

},
child: Text('Second Home'),
),
),
);
}
}

class SecondHome extends StatelessWidget {
User user;

@override
Widget build(BuildContext context) {
RouteSettings settings = ModalRoute.of(context).settings;
user = settings.arguments;

return Scaffold(
appBar: AppBar(
title: Text('${this.user.name} - ${this.user.age}'),
),
body: new Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go Back'),
),
),
);
}
}

class User {
final String name;
final int age;

User({this.name, this.age});
}

RouteSettings will only available when you are using routes in MaterialApp. In other cases, if you will try to call the RouteSettings then you will null as value.

Example 3 : onGenerateRoute

When you will be using onGenerateRoute thenRouteSettings will be unavailable in the SecondHome.

So, How we can send the data to the next screen if we can’t access to the RouteSettings .

We will use a mixture of RouteSettings and Constructor to send the data to the next screen. This approach is one of the best approaches to doing routing in any real-world application.

So, how we can do that?

  • We don’t have direct access to the Constructor but we do have indirect access to the Constructor of the SecondScreen.
  • We don’t have access to the RouteSetting inside the SecondHome but we have access to that outside of SecondHome

Let’s understand how we are having indirect access to the RouterSetting and how we can use the constructor of the SecondHome.

onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (context)=> HomePage());
break;
case '/second':
return MaterialPageRoute(builder: (context)=> SecondPage());
break;
}
  • Here you can see that we are having access to the RouteSettings. If you remember in our previous example I had access the arguments using RouteSettings . So, here also we will use the same approach.

See this example

onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (context) => HomePage());
break;
case '/second':
User user = settings.arguments;
return MaterialPageRoute(
builder: (context) => SecondHome(user: user),
);
break;
}
},
  • Here we are having access to the RouteSettings and arguments.
  • Extract the arguments and pass that to the constructor of the SecondHome.

I hope you got the idea that how you can share the data when you are using onGenerateRoute . Let’s see the full source code

Full Source Code

import 'package:flutter/material.dart';

void main() {
runApp(
MaterialApp(
home: HomePage(),
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (context) => HomePage());
break;
case '/second':
User user = settings.arguments;
return MaterialPageRoute(
builder: (context) => SecondHome(user: user),
);
break;
}
},
),
);
}

class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: new Center(
child: RaisedButton(
onPressed: () {
User user = new User(name: 'Nitish', age: 18);
Navigator.pushNamed(context, '/second', arguments: user);
},
child: Text('Second Home'),
),
),
);
}
}

class SecondHome extends StatelessWidget {
final User user;

SecondHome({this.user});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('${this.user.name} - ${this.user.age}'),
),
body: new Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go Back'),
),
),
);
}
}

class User {
final String name;
final int age;

User({this.name, this.age});
}

Hello World, If you want code for all these example then you need to wait for some time. I’ll add GitHub repository link soon.

You can follow me get the get Notified first by GitHub itself

📝 Read this story later in Journal.

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

--

--

Nitish Kumar Singh

Web🌐/ Mobile📱/ GraphQL / Cloud☁️ . Full-time programmer, part-time content creator, and Freelancer.