- 一、基本路由
- 1. Future push(BuildContext context, Route route)
将给定的路由入栈(即打开新的页面),返回值是一个Future对象,用以接收新路由出栈(即关闭)时的返回数据。 - 2. bool pop(BuildContext context, [ result ])
将栈顶路由出栈,result 为页面关闭时返回给上一个页面的数据。 - 3. 实例方法
Navigator类中第一个参数为context的静态方法都对应一个Navigator的实例方法, 比如Navigator.push(BuildContext context, Route route)等价于Navigator.of(context).push(Route - 3. 通过路由名打开新路由页
要通过路由名称来打开新路由,可以使用Navigator 的pushNamed方法: - 4. 命名路由参数传递
在Flutter最初的版本中,命名路由是不能传递参数的,后来才支持了参数;下面展示命名路由如何传递并获取路由参数: - 5. 适配
假设我们也想将上面路由传参示例中的TipRoute路由页注册到路由表中,以便也可以通过路由名来打开它。但是,由于TipRoute接受一个text 参数,我们如何在不改变TipRoute源码的前提下适配这种情况?其实很简单:
一、基本路由
Navigator是一个路由管理的组件,它提供了打开和退出路由页方法。Navigator通过一个栈来管理活动路由集合。通常当前屏幕显示的页面就是栈顶的路由。Navigator提供了一系列方法来管理路由栈,在此我们只介绍其最常用的两个方法:
1. Future push(BuildContext context, Route route)
将给定的路由入栈(即打开新的页面),返回值是一个Future对象,用以接收新路由出栈(即关闭)时的返回数据。
2. bool pop(BuildContext context, [ result ])
将栈顶路由出栈,result 为页面关闭时返回给上一个页面的数据。
Navigator 还有很多其它方法,如Navigator.replace、Navigator.popUntil等,详情请参考API文档或SDK 源码注释,在此不再赘述。下面我们还需要介绍一下路由相关的另一个概念“命名路由”。
3. 实例方法
Navigator类中第一个参数为context的静态方法都对应一个Navigator的实例方法, 比如Navigator.push(BuildContext context, Route route)等价于Navigator.of(context).push(Route
二、命名路由
所谓“命名路由”(Named Route)即有名字的路由,我们可以先给路由起一个名字,然后就可以通过路由名字直接打开新的路由了,这为路由管理带来了一种直观、简单的方式。
# 1. 路由表
要想使用命名路由,我们必须先提供并注册一个路由表(routing table),这样应用程序才知道哪个名字与哪个路由组件相对应。其实注册路由表就是给路由起名字,路由表的定义如下:
Map
它是一个Map,key为路由的名字,是个字符串;value是个builder回调函数,用于生成相应的路由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注册为命名路由应该怎么做呢?其实很简单,直接看代码:
MaterialApp(
title: 'Flutter Demo',
initialRoute:"/", //名为"/"的路由作为应用的home(首页)
theme: ThemeData(
primarySwatch: Colors.blue,
),
//注册路由表
routes:{
"new_page":(context) => NewRoute(),
"/":(context) => MyHomePage(title: 'Flutter Demo Home Page'), //注册首页路由
}
);
可以看到,我们只需在路由表中注册一下MyHomePage路由,然后将其名字作为MaterialApp的initialRoute属性值即可,该属性决定应用的初始路由页是哪一个命名路由。
可以看到,我们只需在路由表中注册一下MyHomePage路由,然后将其名字作为MaterialApp的initialRoute属性值即可,该属性决定应用的初始路由页是哪一个命名路由。
3. 通过路由名打开新路由页
要通过路由名称来打开新路由,可以使用Navigator 的pushNamed方法:
Future pushNamed(BuildContext context, String routeName,{Object arguments})
Navigator 除了pushNamed方法,还有pushReplacementNamed等其他管理命名路由的方法,读者可以自行查看API文档。接下来我们通过路由名来打开新的路由页,修改TextButton的onPressed回调代码,改为:
onPressed: () {
Navigator.pushNamed(context, "new_page");
//Navigator.push(context,
// MaterialPageRoute(builder: (context) {
// return NewRoute();
//}));
},
热重载应用,再次点击“open new route”按钮,依然可以打开新的路由页。
4. 命名路由参数传递
在Flutter最初的版本中,命名路由是不能传递参数的,后来才支持了参数;下面展示命名路由如何传递并获取路由参数:
我们先注册一个路由:
routes:{
“new_page”:(context) => EchoRoute(),
} ,
在路由页通过RouteSetting对象获取路由参数:
class EchoRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
//获取路由参数
var args=ModalRoute.of(context).settings.arguments;
//…省略无关代码
}
}
在打开路由时传递参数
Navigator.of(context).pushNamed(“new_page”, arguments: “hi”);
5. 适配
假设我们也想将上面路由传参示例中的TipRoute路由页注册到路由表中,以便也可以通过路由名来打开它。但是,由于TipRoute接受一个text 参数,我们如何在不改变TipRoute源码的前提下适配这种情况?其实很简单:
MaterialApp(
… //省略无关代码
routes: {
“tip2”: (context){
return TipRoute(text: ModalRoute.of(context)!.settings.arguments);
},
},
);