Flutter 中的路由与导航
问题1:不同页面的状态怎么管理?
问题2:带参数的导航怎么实现?
-
核心概念
Route 和 Navigator。
定义:
Route :是页面的一个抽象。路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,Route在Android中通常指一个Activity,在iOS中指一个ViewController。
那么,路由就是不同Route之间的跳转。Navigator:是负责管理Route的Widget,并且通过入栈和出栈来实现页面间的跳转。
-
Navigator如何管理
Navigator是一个栈结构,通过push 和pop来操作。push加入一个Route,并将返回一个Future对象。
Future push(BuildContext context, Route route)pop则将栈顶元素出栈。
bool pop(BuildContext context, [ result ])
result为页面关闭时返回给上一个页面的数据。 -
命名的路由(Named Route)
Navigator类中第一个参数为context的静态方法都对应一个Navigator的实例方法, 比如Navigator.push(BuildContext context, Route route)等价于Navigator.of(context).push(Route route) -
携带值的路由跳转
很多情况下在路由跳转时我们需要带一些参数,比如打开商品详情页时,我们需要带一个商品id,这样商品详情页才知道展示哪个商品信息;又比如我们在填写订单时需要选择收货地址,打开地址选择页后,可以将用户选择的地址返回到订单页等等。
非命名路由传值:
通过Navigator.push(context,route)来传递。
值传回:
通过Navigator.pop(context,result),result就是要返回的值。
命名的路由传值:
所谓“命名路由”(Named Route)即有名字的路由,我们可以先给路由起一个名字,然后就可以通过路由名字直接打开新的路由了,这为路由管理带来了一种直观、简单的方式。
起过名字的route需要保存在一张名为(routing tables)的表中。此表的作用是建立route name 与route page的对应关系。
这个表是一个Map<String, WidgetBuilder> routes;
其中key 是路由的名字,value是个builder回调函数。
通过key来查找对应的builder回调函数,生成一个widget并返回。
给路由起名的过程,就是办理路由身份证的过程。通过在页面build方法中添加routes属性。
MaterialApp(
title: 'Flutter Demo',
initialRoute:"/", //名为"/"的路由作为应用的home(首页)
theme: ThemeData(
primarySwatch: Colors.blue,
),
//注册路由表
routes:{
"new_page":(context)=>NewRoute(),
"/":(context)=> MyHomePage(title: 'Flutter Demo Home Page'), //注册首页路由
}
);
使用时,通过Navigator.pushNamed(context,"name")来导航。
命名路由参数传递
通过命名路由通过arguments来传递参数。
Navigator.of(context).pushNamed("new_page", arguments: "hi");
从route的build方法中获取参数。
@override
Widget build(BuildContext context) {
var args=ModalRoute.of(context).settings.arguments;
}
如何把RoutePage类中的某个属性作为接受传参的对象:
在定义命名路由时指定:
比如某个Route页面有一个String 类型的名为text的属性,如何传递给这个属性值,就需要在routes里设置为arguments。
routes:{
"tip_route":
return TipRoute(text: ModalRoute.of(context).settings.arguments);
}
路由生成钩子
钩子就是类似模板方法,用于处理特定情况下的事件。
通过设置onGenerateRoute,来取代路由表,实现跳转前的验证功能。