简介

上篇文章我们讲到了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. 3.7V升压5V,3.7V转5V电路图芯片

    锂离子电池在如今是广泛应用存在我们生活中的方方面面的电子产品中.如,电子玩具,美容仪,医疗产品,智能手表,手机,笔记本,电动汽车等等非常多. 锂电池3.7V升压到5V,3.7V转5V稳压输出的电子产品 ...

  2. C#深拷贝方法

    概述 为什么要用到深拷贝呢?比如我们建了某个类Person,并且实例化出一个对象,然后,突然需要把这个对象复制一遍,并且复制出来的对象要跟之前的一模一样,来看下我们一般会怎么做. 方法一(利用反射实现 ...

  3. pycharm全局搜索

    方法有:1.使用[Ctrl+N]快捷键按文件名搜索py文件: 2.使用[Ctrl+shift+N]快捷键按文件名搜索所有类型的文件: 3.使用[ctrl+shift+f]快捷全局字符串搜索: 3.使用 ...

  4. windows通过sshfs挂载linux目录

    之前讲过一种方法,PC跟VM在同局域网的情况下,可以用samba的方式挂载linux系统的目录到windows上.但是当PC跟VM不同局域网时这种方式就没办法了. 网络环境 在示意图中,PC只能直连物 ...

  5. Transition 初步使用

    Transition Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡: 条件渲染 (使用 v-if) 条件展示 (使用 v-show) 动态组件 ...

  6. BBS项目 未完待续

    项目开发基本流程 1.需求分析 2.架构设计 3.分组开发 4.提交测试 5.交付上线 创建项目配置 环境配置 TEMPLATES = [ { 'BACKEND': 'django.template. ...

  7. [超详细] [效能工具]Typora+PicGo+Github免费图床快速搭建,提升技术文档输出效率

    一.前言 在我们日常的学习和工作中,我们经常需要进行写作.尤其对于我们程序技术人员而言,工作中的技术方案文档或者接口文档等,都是经常需要用上的. 那么如果没有一个高效的工具,去帮助我们记录和创作,这将 ...

  8. 实操记录之-----Ant Design of Vue 增强版动态合并单元格,自动根据数据进行合并,可自定义横纵向合并

    前几天搞了个简易版的动态合并单元格 但是需求有变化,就只能稍微改改了~~ 欢迎路过的各位大佬指出我代码的问题~~~~ 另: 代码执行效率不是很高,如果需要大量渲染更多数据建议可以直接使用原生 < ...

  9. 动力节点——day03

    接收键盘的输入:1.创建一个键盘扫描器对象 java.util.Scanner s=new Scanner(System.in); 2.接收用户输入s.nextInt(); 静态变量在类加载的时候就分 ...

  10. 默认方法:negate-集合信息筛选

    默认方法:negate "与"."或"已经了解了,剩下的"非"(取反)也会简单.默认方法negate的JDK源代码为︰ 集合信息筛选 数组当 ...