Background
Flutter provides two different navigation options.
Option 1. Use Widget class in MaterialPageRoute.
class FirstRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Route'),
),
body: Center(
child: RaisedButton(
child: Text('Open route'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
),
);
}
}
class SecondRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
The key part.
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
Use the Navigator push method and pass the SecondRoute instance to MaterialPageRoute contructor.
If need to pass the paramter.
class FirstRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Route'),
),
body: Center(
child: RaisedButton(
child: Text('Open route'),
onPressed: () {
Navigator.push(
context,
// The parameter passed via SecondRoute constructor.
MaterialPageRoute(builder: (context) => SecondRoute(message: 'The message for second view.')),
);
},
),
),
);
}
}
class SecondRoute extends StatelessWidget {
// This is the parameter the SecondRoute needs.
final String message;
SecondRoute({@required this.message});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
Option 2. Use route.
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: RaisedButton(
child: Text('Launch screen'),
onPressed: () {
// Navigate to the second screen using a named route.
Navigator.pushNamed(context, '/second');
},
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
The key part.
Navigator.pushNamed(context, '/second');
Also need to register the routes in MaterialApp.
void main() {
runApp(MaterialApp(
title: 'Named Routes Demo',
// Start the app with the "/" named route. In our case, the app will start
// on the FirstScreen Widget
initialRoute: '/',
routes: {
// When we navigate to the "/" route, build the FirstScreen Widget
'/': (context) => FirstScreen(),
// When we navigate to the "/second" route, build the SecondScreen Widget
'/second': (context) => SecondScreen(),
},
));
}
If need to pass the paramter.
// When the user taps the button, navigate to a named route
// and provide the arguments as an optional parameter.
Navigator.pushNamed(
context,
'/second',
arguments: 'The message for second view.',
);
Need to do some extra work to get the parameter.
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Gets the parameter from the route. Any type of the parameter is allowed.
final String message = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
The two options
- Widget
- Simple and easy to use.
- This Widget can be used by navigation or Widget tree.
- route
- Extra routes config in MaterialApp.
- Extra work to retrieve the parameter from the route.
- Looks like there's no compile time check for parameter type.
- Cannot be used in Widget tree since there will be no route parameter.
The question
- From the production ready system we should go with which option.
- Why choose one over the other?
Official References