前言
flutter开发过程中一定会用到导航,即:跳转页面和跳回页面.
这一章就主要介绍路由和导航以及导航传值的问题
demo地址(内容在router文件夹中,可以替换main中注释尝试效果)
路由Route和导航Navigator
一个Route是一个屏幕或页面的抽象,Navigator 是管理route的Widget,最常见功能push和pop页面
注意: 当前页面A 跳转 页面B 的前提是,A页面得有导航,否则会报错
push
默认可以使用 Navigator.push来跳转到指定页面,需要使用 MaterialPageRoute包装跳转的页面,如下所示
//默认push
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) => const RouterPage1()));
//先调用 of 在调用 push,这个of返回的 NavigatorState 可以
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) => const RouterPage1()));
//push到某个页面的时候,由于调用的构造方法,可以通过构造方法传参到指定页面
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) => const RouterPage1("我是传递的数据")));
push的同时,接收pop返回的参数,由于push方法是一个 Future,可以通过 await 或者 .then方法来获取(await的前提是,此函数是 async 修饰的异步支持函数)
Navigator
.push(context,
MaterialPageRoute(builder: (context) => const RouterPage1("我是首页传递的数据")))
.then((value) {
log("我是第一页反向传递过来的value");
print(value);
});
扩展push
由于 dart 不能扩展静态方法(静态方法只能通过对应的类名调用,扩展也要通过扩展的类名,看起来很怪),所以我们直接扩展 Navigator.of 返回的 NavigatorState 即可
另外如果要扩展另一种动画的 push, 可以可以写完,在这里面在
extension ExtendNavigator on NavigatorState {
Future pushWidget(Widget widget) {
return push(MaterialPageRoute(builder: (context) => widget));
}
//如果想设置特殊的push动画也可以,也可以在这里面写
}
//调用逻辑
Navigator.of(context).pushWidget(const HomePage());
pop
默认可以使用 Navigator.pop直接跳会上一个页面
//跳转上一个页面
Navigator.pop(context);
//跳转上一个页面同时,传递参数过去
Navigator.pop(context, '我是第一页传递回去的内容');
主动 pop 时,需要注意,在有延迟的操作后执行pop操作时,最后提前判断一下当前页面是是否还存在,否则可能会引起错误
//当前页面还存在的情况在进行pop
if (mounted) {
Navigator.of(context).pop();
}
配置路由名,通过路由名导航
如下所示,在 MaterialApp中设置 routes 路由参数
MaterialApp(
title: "flutter router",
//如果不用名字跳转的话,这一个不用声明
routes: {
'RouterPage1': (BuildContext context) => const RouterPage1(),
'RouterPage2': (BuildContext context) => const RouterPage2(),
'HomePage': (BuildContext context) => const HomeRouterPage(),
},
initialRoute: "HomePage", //设置首页路由,设置了 home 就不用填写了
//home: const HomeRouterPage(),
);
这样就可以通过名字 push 了
用路由名字push
通过,设定的路由名字 name 来push
//通过name push,看起来更适合跳转固定设置好的界面
Navigator.pushNamed(context, "RouterPage1");
//和上面一样
Navigator.of(context).pushNamed("routeName");
ps: routes方式使用起来看起来更加简洁,比较符合react技术栈的风格,但也出现了另外一个问题,就是跳转时构造方法有参数的情况,仍然需需要使用默认的push,否则会出现一系列问题,还有就是特殊页面的不同切换动画问题
替换跟路由
除了直接push、pop还有替换跟路由的,一般是启动页切换正常页面时会用到,因此也没有push默认的返回按钮了
Navigator.of(context).pushReplacementNamed("路由名字"); //替换根路由
最后
路由routes和默认 push 各有各的优点,可以根据情况灵活使用,当然如果嫌两种麻烦的话,最好是直接使用push,稍微自定义一下即可
案例代码很详细,如果想仔细看的话,可以看代码,代码就在 lib/router 文件夹中,快去尝试一下吧