一、命名路由
所谓“命名路由”(Named Route)即有名字的路由,我们可以先给路由起一个名字,然后就可以通过路由名字直接打开新的路由了,这为路由管理带来了一种直观、简单的方式。
1、路由表
我们必须先提供并注册一个路由表(routing table),这样应用程序才知道哪个名字与哪个路由组件相对应。其实注册路由表就是给路由起名字,路由表的定义如下:
Map<String, WidgetBuilder> routes;
它是一个Map
,key
为路由的名字,是个字符串;value
是个WidgetBuilder回调函数
,用于生成相应的路由widget。我们在通过路由名字打开新路由时,应用会根据路由名字在路由表中查找到对应的WidgetBuilder回调函数,然后调用该回调函数生成路由widget并返回。
2、注册路由表
路由表的注册方式很简单,在MyApp类的build
方法中找到MaterialApp
,添加routes
属性,代码如下:
MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
//注册路由表
routes:{
"new_page":(context) => NewRoute(),
... // 省略其它路由注册信息
} ,
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
上面的代码中home
路由并没有使用命名路由,如果我们也想将home
注册为命名路由应该怎么做呢?其实很简单,直接看代码:
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
//注册路由表
routes:{
"new_page":(context) => const TipRoute(text: ''),
"/":(context) => const MyHomePage(title: 'Flutter Demo Home Page'), //注册首页路由
}
);
可以看到,我们只需在路由表中注册一下MyHomePage
路由,然后将其名字写为"/"
即可,就不再需要home:
参数了。应用的初始路由页即是MyHomePage
路由。
3、通过路由名进行跳转
要通过路由名称来打开新路由,可以使用Navigator
的pushNamed
方法。还有pushReplacementNamed
等其他管理命名路由的方法,读者可以自行查看API文档。
onPressed: () {
Navigator.pushNamed(context, "new_page"); // 或者 Navigator.of(context).pushNamed("new_page");
//Navigator.push(context,
// MaterialPageRoute(builder: (context) {
// return NewRoute();
//}));
},
4、命名路由参数传递和获取
下面展示命名路由如何传递并获取路由参数:
1、我们先注册一个路由:
routes:{
"new_page":(context) => EchoRoute(),
} ,
2、在打开路由时传递参数
Navigator.of(context).pushNamed("new_page", arguments: "hi");
或者
Navigator.pushNamed(context, "new_page", arguments: "hi");
3、在路由页通过
RouteSetting
对象获取路由参数:
class EchoRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
//获取路由参数
var args = ModalRoute.of(context).settings.arguments;
//...省略无关代码
}
}
适配
如果我们也想将前面《路由传值(非命名路由)》示例中的
TipRoute
路由页注册到路由表中,以便也可以通过路由名来打开它。但是,由于TipRoute
接受一个text
参数,我们如何在不改变TipRoute
源码的前提下适配这种情况?其实很简单:
答案:
MaterialApp(
... //省略无关代码
routes: {
"tip2": (context){
return TipRoute(text: ModalRoute.of(context).settings.arguments);
},
},
);
二、总结
建议读者最好统一使用命名路由的管理方式,这将会带来如下好处:
1、语义化更明确。
2、代码更好维护;如果使用匿名路由,则必须在调用Navigator.push
的地方创建新路由页,这样不仅需要import
新路由页的dart文件,而且这样的代码将会非常分散。
3、可以通过onGenerateRoute
做一些全局的路由跳转前置处理逻辑。另外,还有一些关于路由管理的内容我们没有介绍,比如 MaterialApp 中还有
navigatorObservers
和onUnknownRoute
两个回调属性,前者可以监听所有路由跳转动作,后者在打开一个不存在的命名路由时会被调用,由于这些功能并不常用,而且也比较简单,我们便不再花费篇幅来介绍了,读者可以自行查看API文档。
网友评论