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
?
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.
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.
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.
Flutter provides two types of APIs for navigation: imperative and declarative.
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). [...]
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With