命名路由(基于onGenerateRoute)
以下介绍如何通过MaterialApp组件的onGenerateRoute属性来管理路由。
1. 从下面代码可以看到,我们不对MaterialApp组件的routes属性进行赋值,而是赋予了其onGenerateRoute属性一个回调函数onGenerateRoute。当查找路由的时候,发现routes属性为null,即会触发onGenerateRoute回调函数,由该回调函数来处理路由。
import 'package:flutter/material.dart';
import 'routes/Routes.dart' show onGenerateRoute;
//code2演示命名路由,传值
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: "/",
onGenerateRoute: onGenerateRoute,
);
}
}
在Routes.dart文件中,可以看到,我们将路由表放在了该文件中。对onGenerateRoute函数,其接受的参数为settings,settings中封装了两个属性,一个是settings.name为路由的名称,另一个是settings.arguments为路由传递的参数。首先执行两层判断,如果请求的路由在路由表在存在,且需要传递参数,则就会调用相应的构造函数去生成页面,pageContentBuilder内部调用的就是页面构造函数。而MaterialPageRoute则是对路由跳转的一种封装,建议使⽤ MaterialPageRoute,因为MaterialPageRoute 已经封装好了,使⽤⽅便,⽽且⾃带⻚⾯切换动画, 并且适配了 Android和iOS, 如果是Android 的话,⻚⾯进⼊动画是向上滑动并淡出, 退出是相反的,如果是 iOS 的话,⻚⾯进⼊动画是从右侧滑⼊,退出是相反的。在这个例子中,实质上展现了通过构造函数来传递参数。
import 'package:flutter/material.dart';
import '../pages/Tabs.dart';
import '../pages/Form.dart';
import '../pages/Search.dart';
import '../pages/Product.dart';
import '../pages/ProductInfo.dart';
final _routes = {
"/": (context) => Tabs(),
"/form": (context) => FormPage(),
"/search": (context, {argument}) => SearchPage(arguments: argument),
"/productinfo": (context, {argument}) => ProductInfoPage(arguments: argument),
"/product": (context) => ProductPage(),
};
//settings: 包含有路由的名称,以及路由所需传递的参数
Route onGenerateRoute(RouteSettings settings) {
final String routeName = settings.name; //路由名称
final routePassArg = settings.arguments; //路由传递的参数
final Function pageContentBuilder = _routes[routeName];
if (pageContentBuilder != null) {
if (routePassArg != null) {
final Route route = MaterialPageRoute(
builder: (context) => pageContentBuilder(
context,
argument: routePassArg,
),
);
return route;
} else {
final Route route = MaterialPageRoute(
builder: (context) => pageContentBuilder(
context,
),
);
return route;
}
}
return null;
}
2. 也可以不采用构造函数传参,将参数传入MaterialPageRoute的settings属性
final Route route = MaterialPageRoute(
builder: (context) => pageContentBuilder(
context,
),
settings: RouteSettings(arguments: routePassArg),//传入参数
);
同样需要在接收方,使用
final Map args = ModalRoute.of(context).settings.arguments;
来接收参数