在Flutter中,我们可以通过扩展PageRoute
(或使用扩展该类的类)来自定义视图更改动画。
例如,我通过使用MaterialApplication
来在CupertinoPageRoute
中将动画更改为“滑动”:
Navigator.of(context).pushReplacement(
CupertinoPageRoute(builder: (context) => Calendar()),
);
现在,我想通过使用main.dart
文件中定义的命名视图来更改它:
return MaterialApp(
title: 'Demo',
theme: myTheme, // => Theme.of(context).copyWith(...)
initialRoute: '/',
routes: {
'/': (context) => Login(),
'/calendar': (context) => Calendar(),
}
);
这样我就可以打电话
Navigator.of(context).pushReplacementNamed('/calendar');
这是IMO更清晰且与视图无关的东西。
这种方法的问题在于我无法定义PageRoute
,因此无法自定义视图更改动画。
有办法吗?
答案 0 :(得分:1)
您可以利用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: "/",
);
}
}
让我们看一下Flutter代码本身。
有一个onGenerateRoute()
提供的框架方法被调用来生成路由。
请查看以下摘录自框架中app.dart文件的摘录。
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;
}
如果routes:
为给定名称提供了构建器,则默认情况下将使用MaterialPageRoute
来生成路由。如果未提供,它将使用您的onGenerateRoute()
方法生成它。
答案 1 :(得分:-1)
我接受了chemamolins的建议并以类似的方式解决了这个问题,但是使用了地图。
我“提取”了routes
对象,并将其放在MaterialApp
之外:
var routes = {
'/': (context) => Login(),
'/calendar': (context) => Calendar()
};
然后我在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));
}
);
}