赞
踩
核心概念
Route 和 Navigator。
1.route:应用程序页面的抽象
2.Navigator,是一个组件管理和维护基于堆栈的历史记录,使用pop和push跳转页面页面间的跳转。
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就是要返回的值。 |
Navigator 继承自 StatefulWidget,它也是小组件,它有很多相关静态函数,可以帮我们达到页面跳转和数据交互的功能:
push 将设置的router信息推送到Navigator上,实现页面跳转。
of 主要是获取 Navigator最近实例的好状态。
pop 导航到新页面,或者返回到上个页面。
canPop 判断是否可以导航到新页面
maybePop 可能会导航到新页面
popAndPushNamed 指定一个路由路径,并导航到新页面。
popUntil 反复执行pop 直到该函数的参数predicate返回true为止。
pushAndRemoveUntil 将给定路由推送到Navigator,删除先前的路由,直到该函数的参数predicate返回true为止。
pushNamed 将命名路由推送到Navigator。
pushNamedAndRemoveUntil 将命名路由推送到Navigator,删除先前的路由,直到该函数的参数predicate返回true为止。
pushReplacement 路由替换。
pushReplacementNamed 这个也是替换路由操作。推送一个命名路由到Navigator,新路由完成动画之后处理上一个路由。
removeRoute 从Navigator中删除路由,同时执行Route.dispose操作。
removeRouteBelow 从Navigator中删除路由,同时执行Route.dispose操作,要替换的路由是传入参数anchorRouter里面的路由。
replace 将Navigator中的路由替换成一个新路由。
replaceRouteBelow 将Navigator中的路由替换成一个新路由,要替换的路由是是传入参数anchorRouter里面的路由。
Flutter 通过 Navigator 来进行页面之间的跳转,分为 push 系列和 pop 系列操作,带 push 方法为入栈操作,带pop 方法为出栈操作。Navigator 的 push 方法分两类,一类是带 Name 的,需要在 MaterialApp 下将 routers 属性进行注册,否则将会找不到该路由,还有一个是不带 Name 的,可以通过 Router 直接跳转。
Navigator.of(context).push(MaterailPageRoute(builder:(context){return BPage();}))
Navigator.of(context).pop();
Navigator.of(context).maybePop();
pushNamed
pushNamed 是命名路由的方式,需要在 MaterialApp 中配置路由名称:
MaterialApp(
title: 'Flutter Demo',
routes: <String, WidgetBuilder>{
'/A': (context) => APage(),
'/B': (context) => BPage(),
},
home: Scaffold(
body: APage(),
),
)
Navigator.of(context).pushNamed('/B');
pushReplacementNamed 和 popAndPushNamed
有A、B、C 三个页面,A页面通过 pushNamed 跳转到 B:
在A页面执行跳转到B
Navigator.of(context).pushNamed('/B');
在B页面执行替换并跳转跳转到C
Navigator.of(context).pushReplacementNamed('/C')
在C页面执行
Navigator.of(context).pop();
发现页面直接返回到A页面
从B页面执行Navigator.of(context).popAndPushNamed
发现popAndPushNamed 路由堆栈和 pushReplacementNamed 是一样,唯一的区别就是 popAndPushNamed 有 B 页面退出动画
pushNamedAndRemoveUntil
有A、B、C、D 四个页面,A 通过push进入 B 页面,B 通过push进入 C 页面,C 通过 pushNamedAndRemoveUntil 进入 D 页面同时删除路由堆栈中直到 /B 的路由,C 页面代码:
RaisedButton(
child: Text('C 页面'),
onPressed: () {
Navigator.of(context).pushNamedAndRemoveUntil('/D', ModalRoute.withName('/B'));
},
),
D 页面按钮执行 pop:
RaisedButton(
child: Text('D 页面'),
onPressed: () {
Navigator.of(context).pop();
},
)
如果想只保留最后的D路由
Navigator.of(context).pushNamedAndRemoveUntil('/D', (Route route)=>false);
popUntil
有如下场景,在入职新公司的时候,需要填写各种信息,这些信息分为不同部分,比如基本信息、工作信息、家庭信息等,这些不同模块在不同页面,填写信息时可以返回上一页,也可以取消,取消返回到首页,此场景可以使用 popUntil,一直 pop 到指定的页面。
RaisedButton(
child: Text('D 页面'),
onPressed: () {
Navigator.of(context).popUntil(ModalRoute.withName('/A'));
},
)
传递数据
有两种方式传递数据:
第一种:通过构造函数方式:
Navigator.of(context).push(MaterialPageRoute(builder: (context){
return ProductDetail(productInfo: productInfo,);
}));
通过命名路由设置参数的方式
RaisedButton(
child: Text('A 页面'),
onPressed: () {
Navigator.of(context).pushNamed('/B',arguments: '来自A');
},
)
B 页面通过 ModalRoute.of(context).settings.arguments
接收数据:
RaisedButton(
child: Text('${ModalRoute.of(context).settings.arguments}'),
onPressed: () {
Navigator.of(context).pushNamed('/C');
},
)
返回数据
B 页面返回代码
RaisedButton(
child: Text('${ModalRoute.of(context).settings.arguments}'),
onPressed: () {
Navigator.of(context).pop('从B返回');
},
)
A 页面接收返回的数据:
class APage extends StatefulWidget { @override _APageState createState() => _APageState(); } class _APageState extends State<APage> { String _string = 'A 页面'; @override Widget build(BuildContext context) { return Scaffold( body: Container( alignment: Alignment.center, child: RaisedButton( child: Text(_string), onPressed: () async { var result = await Navigator.of(context).pushNamed('/B', arguments: '来自A'); setState(() { _string = result; }); }, ), ), ); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。