flutter系列之:Navigator的高级用法
简介
上篇文章我们讲到了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的高级用法的更多相关文章
- flutter系列之:flutter中listview的高级用法
目录 简介 ListView的常规用法 创建不同类型的items 总结 简介 一般情况下,我们使用Listview的方式是构建要展示的item,然后将这些item传入ListView的构造函数即可,通 ...
- EF5+MVC4系列(12) 在主视图中直接用RenderAction调用子Action,并返回视图(Return View)或者分部视图(Return PartialView); 从主Action传值到子Action使用TempData传值;TempData高级用法
结论: ViewData 适用于 在一次请求中 传递数据 . 比如我们从 主Action 到 主视图, 然后在 主视图中 用 RenderAction 请求子Action的时候,就是算作 一次请求 ...
- Solr学习总结(六)SolrNet的高级用法(复杂查询,分页,高亮,Facet查询)
上一篇,讲到了SolrNet的基本用法及CURD,这个算是SolrNet 的入门知识介绍吧,昨天写完之后,有朋友评论说,这些感觉都被写烂了.没错,这些基本的用法,在网上百度,资料肯定一大堆,有一些写的 ...
- sed修炼系列(三):sed高级应用之实现窗口滑动技术
html { font-family: sans-serif } body { margin: 0 } article,aside,details,figcaption,figure,footer,h ...
- Jenkins高级用法 - Jenkinsfile 介绍及实战经验
系列目录 1.Jenkins 安装 2.Jenkins 集群 3.Jenkins 持续集成 - ASP.NET Core 持续集成(Docker&自由风格&Jenkinsfile) 4 ...
- Python进阶:切片的误区与高级用法
2018-12-31 更新声明:切片系列文章本是分三篇写成,现已合并成一篇.合并后,修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章节衔接做了大量改动.原系列的单篇就不删除了,毕竟也是 ...
- [转]DELL PERC 系列阵列卡选型和用法指南
引用地址 https://www.sulabs.net/?p=895 DELL PERC 系列阵列卡选型和用法指南 2018年12月29日 Su 本文缘起于一位朋友在生产服务器硬件中,使用了错误的阵列 ...
- Web Scraper 高级用法——抓取属性信息 | 简易数据分析 16
这是简易数据分析系列的第 16 篇文章. 这期课程我们讲一个用的较少的 Web Scraper 功能--抓取属性信息. 网页在展示信息的时候,除了我们看到的内容,其实还有很多隐藏的信息.我们拿豆瓣电影 ...
- 多年经验,教你写出最惊艳的 Markdown 高级用法
点赞再看,养成习惯,微信搜索[高级前端进阶]关注我. 本文 GitHub https://github.com/yygmind 已收录,有一线大厂面试完整考点和系列文章,欢迎 Star. 最近在学习的 ...
- 多年经验总结,写出最惊艳的 Markdown 高级用法
点赞再看,养成习惯,微信搜索[高级前端进阶]关注我. 本文 GitHub https://github.com/yygmind 已收录,有一线大厂面试完整考点和系列文章,欢迎 Star. 最近在学习的 ...
随机推荐
- On Java 8读书笔记
第一章 什么是对象 1.1 抽象的历程 "对象":问题空间中的元素及其解决方案空间中的具体呈现. 理念即是通过添加各种新的对象,可以将程序改编为一种描述问题的语言. 对象是具有状态 ...
- 漫谈计算机网络:番外篇 ------网络安全相关知识——>公钥与私钥、防火墙与入侵检测
<漫谈计算机网络>上次已经完结啦,今天出一个番外篇! 2022-12-06 今天我们来聊一聊网络安全 废话不多说直接进入正题 网络安全问题概述 计算机网络面临的安全性威胁 两大类威胁:被动 ...
- MassTransit 知多少 | 基于MassTransit Courier实现Saga 编排式分布式事务
Saga 模式 Saga 最初出现在1987年Hector Garcaa-Molrna & Kenneth Salem发表的一篇名为<Sagas>的论文里.其核心思想是将长事务拆分 ...
- 构建SpringCloud网关服务
搭建网关 导入maven包: <!--网关依赖--> <dependency> <groupId>org.springframework.cloud</gro ...
- java中对象存在形式
本文主要讲述jvm中对象的存储形式: class Cat{ String name; int age; String color; // 行为 } 依据Cat类创建对象 public class Ob ...
- Vue element 自定义表单验证(验证手机号)
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" ...
- JavaScript:操作符:比较运算符及其隐式转换数据类型
不等关系 即大于>:大于等于>=:小于<:小于等于<= 当比较的两个变量,有非数字时,会隐式转换为数字再比较,转换情况同算术运算符: 当两个变量均为字符串时,不会进行转换,而是 ...
- error: expected ‘)’ before ‘PRIx64’
打印uint64时编译报错 printf("prefix:0x%"PRIx64"\n",ipv6Prefix); 解决办法:添加头文件 #include < ...
- Vue中实现自定义excel下载
目录 第一种:后端生成excel 第二种:前端合成excel 总结 参考资料 最近在工作中遇到一个需求,就是需要在前端实现一个错误模板Excel的下载功能. 实现下载有两种方式,一种是后端生成一个ex ...
- [编程基础] Python随机数生成模块总结
Python随机数生成模块教程演示如何在Python中生成伪随机数. 1 介绍 1.1 随机数字生成器 随机数生成器(RNG)生成一组在外观上不显示任何可区分模式的值.随机数生成器分为两类:硬件随机数 ...