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. 最近在学习的 ...
随机推荐
- 1.3 Apache Hadoop的重要组成-hadoop-最全最完整的保姆级的java大数据学习资料
目录 1.3 Apache Hadoop的重要组成 1.3 Apache Hadoop的重要组成 Hadoop=HDFS(分布式文件系统)+MapReduce(分布式计算框架)+Yarn(资源协调框架 ...
- 【Java SE进阶】Day02 Collection、Iterator、泛型
一.Collection集合 1.概述 数组存元素,集合存对象(类型可以不一样) 2.框架分类 单列:Collection List ArrayList LinkedList Set HashSet ...
- 【SQL知识】SQL中的join操作总结:内连接、外连接(左右全)
一.含义 基于表之间的共同字段,把来自两个或多个表的行结合起来 二.分类 内连接:join / inner join 外连接:left join / right join / full outer j ...
- Pytorch框架详解之一
Pytorch基础操作 numpy基础操作 定义数组(一维与多维) 寻找最大值 维度上升与维度下降 数组计算 矩阵reshape 矩阵维度转换 代码实现 import numpy as np a = ...
- python之字典(dict)创建与使用
字典(dict) 在其他语言中被称为哈希映射(hash map)或者相关数组,它是一种大小可变的键值对集,其中的key.value都是python对象. 特别注意: 1.字典中的key不能重复,key ...
- django serializer.is_valid()总是返回False({'invalid': '无效数据。期待为字典类型,得到的是 {datatype} 。'})
在调用添加接口时,一值失败,调试后发现传入的数据并没有问题,但是数据验证时一直返回False,此时使用 serializer.error_messages查看,所返回如下问题: 再往上看显示: 发现 ...
- Django(2) - Django模板
1.Django模板介绍 基础概念 模板是具有一定的格式或骨架,可以动态的生成HTML 模板引擎决定以何种方式组织代码 一个项目可以有一个或者是多个模板引擎,Django里面主要两个模板引擎:DTL. ...
- 求和【第十三届蓝桥杯省赛C++A/C组 , 第十三届蓝桥杯省赛JAVAA组】
求和 给定 \(n\) 个整数 \(a1,a2,⋅⋅⋅,an\),求它们两两相乘再相加的和,即 \(S=a1⋅a2+a1⋅a3+⋅⋅⋅+a1⋅an+a2⋅a3+⋅⋅⋅+an−2⋅an−1+an−2⋅a ...
- 蚂蚁感冒【第五届蓝桥杯省赛C++A/B组】
蚂蚁感冒 长 \(100\) 厘米的细长直杆子上有 \(n\) 只蚂蚁. 它们的头有的朝左,有的朝右. 每只蚂蚁都只能沿着杆子向前爬,速度是 1 厘米/秒. 当两只蚂蚁碰面时,它们会同时掉头往相反的方 ...
- [C++]C++11:Function与Bind
std::function 它是函数.函数对象.函数指针.和成员函数的包装器,可以容纳任何类型的函数对象,函数指针,引用函数,成员函数的指针. 以统一的方式处理函数.函数对象.函数指针.和成员函数. ...