Reputation: 22233
In Flutter we can customize the view-change animation by extending PageRoute
(or by using a class which extends that).
For instance, I'm changing the animation to "slide" in my MaterialApplication
by using the CupertinoPageRoute
that way:
Navigator.of(context).pushReplacement(
CupertinoPageRoute(builder: (context) => Calendar()),
);
Now I want to change that by using named views defined in the main.dart
file:
return MaterialApp(
title: 'Demo',
theme: myTheme, // => Theme.of(context).copyWith(...)
initialRoute: '/',
routes: {
'/': (context) => Login(),
'/calendar': (context) => Calendar(),
}
);
This way I can just call
Navigator.of(context).pushReplacementNamed('/calendar');
Which is IMO clearer and view-agnostic.
The issue with this approach is that I can't define a PageRoute
, so I can't customize the view-change animation.
Is there a way to do that?
Upvotes: 6
Views: 4183
Reputation: 22233
I took chemamolins' advice and solved it in a similar way, but using maps.
I "extracted" the routes
object and put it outside MaterialApp
:
var routes = {
'/': (context) => Login(),
'/calendar': (context) => Calendar()
};
Then I used it inside onGenerateRoute
:
Widget build(BuildContext context) {
var routes = {
'/': (context) => Login(),
'/calendar': (context) => Calendar()
};
return MaterialApp(
title: 'Demo',
theme: myTheme,
initialRoute: '/',
onGenerateRoute: (settings) {
return CupertinoPageRoute(builder: (context) => routes[settings.name](context));
}
);
}
Upvotes: 6
Reputation: 20548
You could leverage onGenerateRoute()
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
Route onGenerateRoute(RouteSettings settings) {
Route page;
switch (settings.name) {
case "/":
page = CupertinoPageRoute(builder: (context) => Login());
break;
case "/calendar":
page = CupertinoPageRoute(builder: (context) => Calendar());
break;
}
return page;
}
@override
Widget build(BuildContext context) {
return new WidgetsApp(
onGenerateRoute: onGenerateRoute,
initialRoute: "/",
);
}
}
Let's give a look to the Flutter code itself.
There is a framework provided onGenerateRoute()
method called to generate the routes.
Look at the following snippet taken from the app.dart file in the framework.
Route<dynamic> _onGenerateRoute(RouteSettings settings) {
final String name = settings.name;
WidgetBuilder builder;
if (name == Navigator.defaultRouteName && widget.home != null) {
builder = (BuildContext context) => widget.home;
} else {
builder = widget.routes[name];
}
if (builder != null) {
return new MaterialPageRoute<dynamic>(
builder: builder,
settings: settings,
);
}
if (widget.onGenerateRoute != null)
return widget.onGenerateRoute(settings);
return null;
}
If the routes:
provides a builder for a given name, it is used to generate the route using MaterialPageRoute
by default. If it is not provided, it goes to generate it by using your onGenerateRoute()
method.
Upvotes: 2