Flutter开发 -- 导航

省流:官网也在强推go_router,各位看官可以跳到使用路由那块直接看。

导航对于任何应用程序都非常重要。它为各种平台提供的导航 API 提供了统一的抽象。Flutter 为导航提供了两种类型的 API:命令式和声明式。## 命令式导航最常用的一种导航的方式,也是最简单的一种。命令式导航由一个栈的Widget组成,通过push压栈,通过pop从栈里弹出。push方法让你导航的一个新的页面,而pop则从当前页面返回到上一个页面。我们来看一个简单的例子:
注意push之后就会跳转到DetailScreen了。

在DetailScreen调用pop可以返回:

Navigator类提供了导航需要的所有功能。同时,还提供了一个pushReplaceent的方法。这个方法和push类似,但是会把当前路由删除,也就是说导航到新的页面之后再导航回来是不可能的。这个场景正好适合登录,登录成功之后用户无法回退到登录页面。

命名导航

使用命名导航,你可以只用字符串就切换不同的页面。这主要是通过定义一个路由字典实现的。

定义路由

路由的定义由字符串为Key,页面实例为值的字典组成。然后传入到MaterialApp的routes属性:

在我们的todo app里面的修改可以是这样的:

随后就要修改HomeScreen跳转的方法:注释掉的就是我们之前用的导航代码。现在使用了Navigator.pushNamed这个方法,然后传入定义好的路由的名称detail就可以跳转到详细页面了。

传递数据

在导航中传递参数

就如上例中我们提到的,从todo 列表页跳转到详细页的时候还显示的是一个可以回退的按钮。这是我们为了显示导航的功能而做的。但是这是不够的。在跳转到详细页的时候本来应该展示的是todo的详情内容。这就需要导航到新的页面的时候还要把数据也一起传递过去。另外还要介绍一个情况就是,从新的路由里返回数据。

最简单的一种方法是在push的时候,初始化DetailScreen的时候给他传入一个参数,也就是给DetailScreen添加一个构造函数参数。这里就不细说了。

真正的参数是这样传递的:

在push的时候,在MaterialPageRoute里给settings值。然后,在DetailScreen中把参数读取出来:final todo = ModalRoute.of(context)!.settings.arguments as TodoItem;就是用来读取导航传递的参数的。


在导航中返回数据

现在来实现返回数据的功能。比如,如果一个用户查看了todo的内容,那么就返回以后弹出一个"已读"的snackbar。就像这样:

首先修改HomeScreen的代码:

主要看第二行,给push的方法加一个await,然后读取一个返回值给result赋值。得到值之后显示一个snackbar说明todo详情已读。

之后修改DetailScreen页面。需要改的地方不多,只要改pop加一个需要返回的值作为参数。像这样:Navigator.pop(context, '${todo.content} is read');。

以上都是在命令导航中传递参数的方法。先在看看如何在命名导航中传递参数。

首先,需要在MaterialApp中配置routes属性。这个前文已经讲过了。然后在pushNamed加上要传递的参数。

然后在DetailScreen里读取参数。还是老方法:

在新一版本的Flutter中,引入了基于Page的导航。这些在第三方库中广泛使用,比如go_router。有兴趣的可以了解一下。

注意:Flutter不推荐使用命名导航的方式。主要是因为命名路由在支持deep link和flutter web的时候有问题

使用路由

这是一个声明式的方式定义路由的方法。在前面讲到的内容中,如果要同时push或者pop多个页面,或者对当前页面以外的路由操作都不是很容易。Router,我们要讲的,可以非常容易的处理以上的问题。

具体基于pages的路由可以参考官网。在后续的deep link的讲解中会用到go_router。所以,我们这里着重讲解一下这个库的一些常用方法。

首先下载go_router包。

然后去掉之前的所有路由的代码,添加基于go_router的代码:

修改的时候,只需要把之前的MaterialApp改成MaterialApp.router。其他的不用改,之后把routes改成routerConfig。

routerConfig添加一些路由: "/"这个路由对应的就是HomeScreen,"/detail"对应的就是DetailScreen页面。"/settings"对应的就是SettingsScreen。

在settings这个路由下还有一个子路由:"isolate"。这是go_router的子路由。

在导航到下一个页面的时候可以使用context.push(目标路由)的方式也可以使用context.go(目标路由)的方式。二者路由有区别。使用go的方式,之前的路由历史会被清理出路由栈。在使用的时候需要注意!

使用push跳转到设置页:

使用go跳转到isolate页面:

就是这么简单!

使用go_router的情况下,如何传递参数呢?也很简单。

路径参数(path params)

查询参数(query params)

在导航的时候可以这样:

附加参数(extra params)

导航的时候:

带值pop

使用go_router一样可以实现pop回来同时传递参数的效果:在HomeScreen里导航到DetailScreen。这个额外需要做的就是要在push的时候await。同时接收返回的结果。

在得到结果之后显示一个snackbar。

在DetailScreen里,pop回来的时候context.pop(widget.todo.content);。pop回来的时候到这一个参数,它的值是跳转过去的todo的内容。

运行起来看看吧!

相关推荐
2501_9159214317 小时前
如何在苹果手机上面进行抓包?iOS代理抓包,数据流抓包
android·ios·智能手机·小程序·uni-app·iphone·webview
Boyang_18 小时前
在 iOS 26 上@property 的一个小 bug
ios
_李小白18 小时前
【Android 美颜相机】第五天:GPUImageFilterTools
android·数码相机
冬奇Lab18 小时前
【Kotlin系列05】集合框架:从Java的冗长到函数式编程的优雅
android·kotlin·编程语言
奋斗的小青年!!18 小时前
Flutter开发OpenHarmony打卡进度环组件:实现与跨平台兼容性实践
flutter·harmonyos·鸿蒙
冬奇Lab18 小时前
稳定性性能系列之十四——电量与网络优化:Battery Historian与弱网处理实战
android·性能优化·debug
Coffeeee18 小时前
了解一下Android16更新事项,拿捏下一波适配
android·前端·google
用户416596736935518 小时前
深入解析安卓 ELF 16KB 页对齐:原生编译与脚本修复的权衡
android
七牛云行业应用18 小时前
iOS 19.3 突发崩溃!Gemini 3 导致 JSON 解析失败的紧急修复
人工智能·ios·swift·json解析·大模型应用
消失的旧时光-194318 小时前
Flutter 列表 + Riverpod 架构实战 —— 从 setState 到状态驱动列表的工程落地
flutter