Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between onGenerateRoute and routes in Flutter

Tags:

flutter

dart

What is the benefit or use case of onGenerateRoute and routes in Flutter.

In my application in first page inside MaterialApp we can define routes for our Application the same thing we can define with onGenerateRoute.

Both are used for NamedRoute.

I am unsure, in which scenario I need to use routes and in which scenario I need to use onGenerateRoute?

like image 805
MSARKrish Avatar asked Jan 20 '20 11:01

MSARKrish


People also ask

What are the difference between onGenerateRoute and ModalRoute of () in Flutter?

ModalRoute. of is used to build the route after it has been pushed in the navigation history. onGenerateRoute does the same, but before that route is pushed in the navigation history.

What is onGenerateRoute in Flutter?

onGenerateRoute property: The route generator callback used when the app is navigated to a named route. ... This is used if routes does not contain the requested route.

What is the use of routes in Flutter?

An app has to display multiple screens depending upon the user's needs. A user needs to back and forth from the multiple screens to the home screen. In, Flutter this is done with the help of Navigator. Note: In Flutter, screens and pages are called routes.

How many types of navigation are there in Flutter?

Flutter provides two types of APIs for navigation: imperative and declarative.


2 Answers

NB (see comments below answer):

There is no bug, just bad usage by the issue reporter. It is caused because he didn't pass the settings object along to the new MaterialPageRoute returned by the onGenerateRoute method (see the issue's final comments). [...]


Original answer mentionning a "bug":

Without diving into any details those two properties do the same thing, but as @Alireza noted routes is checked first.

Also, using onGenerateRoute gives you a single place to add your custom business logic before pushing new routes (pages). For example, if you want to do some initializations.

routes property:

When a named route is pushed with Navigator.pushNamed, the route name is looked up in this map. If the name is present, the associated WidgetBuilder is used to construct a MaterialPageRoute that performs an appropriate transition, including Hero animations, to the new route.

onGenerateRoute property:

The route generator callback used when the app is navigated to a named route. ... This is used if routes does not contain the requested route.

IMPORTANT: What you really want to be aware of is a known bug in onGenerateRoute property.

The problem is that if you use onGenerateRoute to create named routes you won't be able to get the name of that route from RouteSettings object in your page. (Arguments attached to the settings object are fine though) In other words:

Widget build(BuildContext context) {     ModalRoute.of(context).settings.name == null;       //bug     ModalRoute.of(context).settings.arguments != null;  //ok     ... 

This may affect you in case you would like to know the name of the current route. For example, if you want to pop some screens:

navigator.popUntil(ModalRoute.withName('/login')); 

Therefore, until this problem is resolved, I recommend using the routes: property.

like image 157
Kirill Karmazin Avatar answered Sep 28 '22 05:09

Kirill Karmazin


routes is static and doesn't offer functionalities like passing an argument to the widget, implementing a different PageRoute etc, which is why onGenerateRoute exists.

In the given code, you'll find that how using onGenerateRoute property, you can parse an argument and send it over, which isn't possible with simple routes.

FooPage is navigated through routes and BarPage through onGenerateRoute.


Initial setup in MaterialApp.

void main() {   runApp(     MaterialApp(       routes: {         '/': (_) => HomePage(), // You can also use MaterialApp's `home` property instead of '/'         '/foo': (_) => FooPage(), // No way to pass an argument to FooPage.       },       onGenerateRoute: (settings) {         if (settings.name == '/bar') {           final value = settings.arguments as int; // Retrieve the value.           return MaterialPageRoute(builder: (_) => BarPage(value)); // Pass it to BarPage.         }         return null; // Let `onUnknownRoute` handle this behavior.       },     ),   ); } 

home.dart:

class HomePage extends StatelessWidget {   @override   Widget build(BuildContext context) {     return Scaffold(       appBar: AppBar(title: Text('HomePage')),       body: Center(         child: Column(           children: [             ElevatedButton(               onPressed: () => Navigator.pushNamed(context, '/foo'),               child: Text('Go to FooPage'),             ),             ElevatedButton(               onPressed: () => Navigator.pushNamed(context, '/bar', arguments: 42), // Passing argument               child: Text('Go to BarPage'),             ),           ],         ),       ),     );   } } 

foo.dart

class FooPage extends StatelessWidget {   @override   Widget build(_) => Scaffold(appBar: AppBar(title: Text('FooPage'))); } 

And bar.dart:

class BarPage extends StatelessWidget {   final int value;   BarPage(this.value);    @override   Widget build(_) => Scaffold(appBar: AppBar(title: Text('BarPage, value = $value'))); } 

Screenshot (for reference)

enter image description here

like image 26
CopsOnRoad Avatar answered Sep 28 '22 04:09

CopsOnRoad