简介

上篇文章我们讲到了flutter中navigator的基本用法,我们可以使用它的push和pop方法来进行Router之间的跳转。

在flutter中一个Router就是一个widget,但是在Android中,一个Router就是Activity,在IOS中,一个Router是一个ViewController。

Router除了之前讲过的push和pop方法之外,还有一些更加高级的用法,一起来看看吧。

named routes

虽然在flutter中navigator将routers以stack的形式进行存储,能做的也只是push和pop操作,但是事实上Router是可以有名字的。

想想也是,如果Router没有名字的话,那么如何顺利进行跳转呢?不可能每次都new一个Router出来吧。

navigator有一个方法叫做Navigator.pushNamed()用来将带名字的Router压入堆栈,我们来看下它的定义:

  static Future<T?> pushNamed<T extends Object?>(
BuildContext context,
String routeName, {
Object? arguments,
}) {
return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
}

这个方法需要传入一个context和对应的routeName,同时还可以带一些参数。

那么怎么用这个方法呢?

首先我们需要定义一些Router,比如说在创建MaterialApp的时候可以传入routes参数,来设置named Routers:

MaterialApp(
title: '这是named Routers',
initialRoute: '/firstPage',
routes: {
'/firstPage': (context) => const FirstPage(),
'/secondPage': (context) => const SecondPage(),
},
)

上面的代码中我们分别定了两个routers,分别是firstPage和secondPage,他们分别对应一个自定义的widget。

定义好Router之后,我们就可以向下面这样使用了:

onPressed: () {
Navigator.pushNamed(context, '/secondPage');
}

如果要返回第一个页面的话,那么可以调用Navigator.pop方法来实现:

onPressed: () {
Navigator.pop(context);
}

给named route传参数

在上一节我们讲到pushNamed的时候,还介绍了它还可以接收参数arguments。从定义上可以看到arguments的类型是Object对象,也就是说任何对象都可以作为named route的参数。

那么我们先定义一个对象如下:

class TestArguments {
final String name;
final String description; TestArguments(this.name, this.description);
}

接下来我们需要创建一个能够接受这个参数的Routers。

因为所有的Routers都是Widget,所以我们需要创建一个Widget,并在这个widget内部接收传入的参数。

在flutter中有两种传递参数的方式,你可以使用ModalRoute.of(),也可以使用onGenerateRoute()。

我们先来看下ModalRoute.of的定义:

  static ModalRoute<T>? of<T extends Object?>(BuildContext context) {
final _ModalScopeStatus? widget = context.dependOnInheritedWidgetOfExactType<_ModalScopeStatus>();
return widget?.route as ModalRoute<T>?;
}

它接收一个context参数,然后返回一个route对象。

具体的用法如下:

class FirstPage extends StatelessWidget {
const FirstPage({super.key}); static const routeName = '/firstPage'; @override
Widget build(BuildContext context) { final args = ModalRoute.of(context)!.settings.arguments as TestArguments; return Scaffold(
appBar: AppBar(
title: Text(args.name),
),
body: Center(
child: Text(args.description),
),
);
}
}

除了使用ModalRoute之外,还可以在onGenerateRoute()方法中进行参数传递。onGenerateRoute是在Route生成的时候触发的:

MaterialApp(

  onGenerateRoute: (settings) {

    if (settings.name == FirstPage.routeName) {

      final args = settings.arguments as TestArguments;

      return MaterialPageRoute(
builder: (context) {
return TestArguments(
title: args.title,
message: args.message,
);
},
);
}
return null;
},
)

onGenerateRoute接收一个settings对象,我们需要在settings对象中设置对应的name和arguments属性。所以我们需要这样调用:

    Navigator.pushNamed(
context,
FirstPage.routeName,
arguments: TestArguments(
'测试',
'这是一个named Route',
),
);

从Screen返回值

有时候我们需要从一个Screen返回到之前的Screen,并且不是简单的返回,我们还希望知道前一个screen返回了什么结果,然后可以根据前一个screen返回的不同结果来进行不同的处理。

这个时候就需要用到Navigator.pop的传参功能了。

比如我们在第一个页面中点击了按钮,跳转到第二个页面:

  final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SecondScreen()),
);

这里我们使用到了Navigator.push方法,并且返回了一个result的值。

我们可以使用这个值来进行一些逻辑判断。

那么这个result的值是哪里传递过来的呢?

没错,就是SecondScreen中的Navigator.pop方法:

Navigator.pop(context, 'Yes');

这里的'Yes'就会传递给result供我们进行逻辑判断。

向Screen传值

有时候我们需要在页面跳转的过程中传递一些参数,那么怎么才能实现Screen之间的参数传递呢?

因为在flutter中所有的Routers都是Widget,所以我们可以在跳转到新的页面的时候直接将参数以构造函数的方式传递给Routers Widget。

比如我们有下面的Screen Widget:

class NameScreen extends StatelessWidget {

  const NameScreen({super.key, required this.name});

  final String name;

  @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('NameScreen'),
), body:
...
;
}
}

想要传值给它,可以在onTap方法中这样写:

onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NameScreen(name: 'what is your name?'),
),
);

总结

以上就是Navigator的更加高级的用法,我们可以通过Navigator来进行数据传递等操作,从而实现更加复杂的页面功能。

flutter系列之:Navigator的高级用法的更多相关文章

  1. flutter系列之:flutter中listview的高级用法

    目录 简介 ListView的常规用法 创建不同类型的items 总结 简介 一般情况下,我们使用Listview的方式是构建要展示的item,然后将这些item传入ListView的构造函数即可,通 ...

  2. EF5+MVC4系列(12) 在主视图中直接用RenderAction调用子Action,并返回视图(Return View)或者分部视图(Return PartialView); 从主Action传值到子Action使用TempData传值;TempData高级用法

    结论: ViewData 适用于 在一次请求中 传递数据  . 比如我们从 主Action 到 主视图, 然后在 主视图中  用 RenderAction 请求子Action的时候,就是算作 一次请求 ...

  3. Solr学习总结(六)SolrNet的高级用法(复杂查询,分页,高亮,Facet查询)

    上一篇,讲到了SolrNet的基本用法及CURD,这个算是SolrNet 的入门知识介绍吧,昨天写完之后,有朋友评论说,这些感觉都被写烂了.没错,这些基本的用法,在网上百度,资料肯定一大堆,有一些写的 ...

  4. sed修炼系列(三):sed高级应用之实现窗口滑动技术

    html { font-family: sans-serif } body { margin: 0 } article,aside,details,figcaption,figure,footer,h ...

  5. Jenkins高级用法 - Jenkinsfile 介绍及实战经验

    系列目录 1.Jenkins 安装 2.Jenkins 集群 3.Jenkins 持续集成 - ASP.NET Core 持续集成(Docker&自由风格&Jenkinsfile) 4 ...

  6. Python进阶:切片的误区与高级用法

    2018-12-31 更新声明:切片系列文章本是分三篇写成,现已合并成一篇.合并后,修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章节衔接做了大量改动.原系列的单篇就不删除了,毕竟也是 ...

  7. [转]DELL PERC 系列阵列卡选型和用法指南

    引用地址 https://www.sulabs.net/?p=895 DELL PERC 系列阵列卡选型和用法指南 2018年12月29日 Su 本文缘起于一位朋友在生产服务器硬件中,使用了错误的阵列 ...

  8. Web Scraper 高级用法——抓取属性信息 | 简易数据分析 16

    这是简易数据分析系列的第 16 篇文章. 这期课程我们讲一个用的较少的 Web Scraper 功能--抓取属性信息. 网页在展示信息的时候,除了我们看到的内容,其实还有很多隐藏的信息.我们拿豆瓣电影 ...

  9. 多年经验,教你写出最惊艳的 Markdown 高级用法

    点赞再看,养成习惯,微信搜索[高级前端进阶]关注我. 本文 GitHub https://github.com/yygmind 已收录,有一线大厂面试完整考点和系列文章,欢迎 Star. 最近在学习的 ...

  10. 多年经验总结,写出最惊艳的 Markdown 高级用法

    点赞再看,养成习惯,微信搜索[高级前端进阶]关注我. 本文 GitHub https://github.com/yygmind 已收录,有一线大厂面试完整考点和系列文章,欢迎 Star. 最近在学习的 ...

随机推荐

  1. 【Shell案例】【打印指定行用sed、for循环、head和tail配合使用】4、输出第5行的内容

    描述写一个 bash脚本以输出一个文本文件 nowcoder.txt 中第5行的内容. 示例:假设 nowcoder.txt 内容如下:welcometonowcoderthisisshellcode ...

  2. 【Java SE】Day08 String类、static关键字、Arrays类、Math类

    一.String类 1.概述 所有双引号字符串,都是String类的对象 字符串常量,会存在字符串常量池中 2.创建 构造函数--空构造.字符数组.字节(byte ASCII码)数组 3.常用方法-- ...

  3. 基于opencv实现简单人脸检测

    作用:在视频中自动检测出人脸 使用内容:灰度转换,分类器,矩形框选,圆形框选,摄像头读取及释放 代码逻辑: 先读取摄像头后, 对摄像头拍摄到的图片进行逐帧分析, 并对图像进行灰度转换后使用类选择器识别 ...

  4. DenseNet 论文解读

    目录 目录 摘要 网络结构 优点 代码 问题 参考资料 摘要 ResNet 的工作表面,只要建立前面层和后面层之间的"短路连接"(shortcut),就能有助于训练过程中梯度的反向 ...

  5. java中的数值运算

    本文主要是掌握java中的整除和取模的运算: public class MathOperate { public static void main(String[] args) { // 取整运算 S ...

  6. uniapp 微信小程序 引入 环信聊天

    最近项目需要实现一个聊天的功能,群聊或者单聊,用到环信,根据官网实现一下相关的配置吧 第一:下载环信demo  地址:https://github.com/easemob/webim-uniapp-d ...

  7. [数据结构]克鲁斯卡尔(Kruskal)算法

    算法的概念 与Prim算法从顶点开始扩展最小生成树不同,Kruskal算法是一种按权值的递增次序选择合适的边来构造最小生成树的方法.假设N=(V,E)是连通网,对应的最小生成树T=(Vt,Et),Kr ...

  8. 【转】C#接口知识

    参考:日常收集 C# 接口知识 (知识全面) 目录 第一节 接口慨述 第二节 定义接口 第三节 定义接口成员 第四节.访问接口 第五节.实现接口 第六节.接口转换 第七节.覆盖虚接口 第一节 接口慨述 ...

  9. JUC并发编程

    什么是JUC java.util.concurrent* public class Test1 { public static void main(String[] args) { //获取处理器核数 ...

  10. 编程思想转换-Lambda表达式

    编程思想转换 做什么,而不是怎么做 我们真的希望创建一个匿名内部类对象吗?不.我们只是为了做这件事情而不得不创建一个对象.我们真正希望做的事情是︰将run方法体内的代码传递给 Thread类知晓. 传 ...