Flutter路由管理(二)

路由(Route)在移动开发中通常是指页面(Page),这与Web开发的意义是相同的,Route在Andriod中通常指一个Activaty,在IOS中指一个ViewController,路由入栈(push)用于打开一个新页面,路由出栈(pop)操作用于对应页面关闭操作,路由管理则是指如何管理路由栈。

1、示例

  • 创建一个新路由,新页面在页面中间显示一句话
class NewRoute extends StatelessWidget {const NewRoute({super.key});Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("新页面"),),body: const Center(child: Text("新路由"),),);}
}
  • 在main.dart的_MyHomePageState类中添加以下按钮
ElevatedButton(style: ButtonStyle(foregroundColor:WidgetStateProperty.all(Colors.amberAccent)),onPressed: () {Navigator.push(context, MaterialPageRoute(builder: (context) {return const RouteTestRoute();}));},child: const Text("路由管理")),
1.1 MaterialPageRoute
MaterialPageRoute({required this.builder,super.settings,this.maintainState = true,super.fullscreenDialog,super.allowSnapshotting = true,super.barrierDismissible = false,
})
  • required this.builder:是一个必填的参数,这是一个回调函数,用于构建目标页面的Widget;
  • super.settings:设置对象,用于定义路由的一些元数据,如路由的名字、是否为初始路由等;
  • this.maintainState:入栈新路由时,是否保留在内存的原来路由,设置为false则在路由没用时释放其占用的所有内存;
  • super.fullscreenDialog:表示新的路由是否为一个全屏的模糊对话框,在IOS中,设置为true,则新页面会从屏幕底部划入,而不是在水平方向;
  • super.allowSnapshotting:表示是否允许快照,快照是指当页面不在前台是保留其状态,以便在回到前台是快速恢复;
  • super.barrierDismissible:表示是否可以通过点击页面之外的区域来关闭对话框,对于非全屏的路由,这个属性通常用于控制是否可以点击背景来关闭对话框。
1.2 Navigator
  • 常用方法:
    • push(Route route):向 Navigator 的页面堆栈中添加一个新的页面。这通常用于启动一个新的活动或显示一个对话框;
    • pop([dynamic result]):从 Navigator 的页面堆栈中移除顶部的页面并返回到前一个页面。result 参数是可选的,可以用来传递结果数据给前一个页面;

2、路由传值

2.1 创建TipRoute路由

这个路由的功能是接受一个提示文本参数,并将参数显示在页面上,点击返回按钮后会向上一个页面带上一个返回参数。

class TipRoute extends StatelessWidget {const TipRoute({super.key, required this.text});final String text;Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("提示"),),body: Padding(padding: const EdgeInsets.all(18),child: Center(child: Column(children: [Text(text),ElevatedButton(onPressed: () => Navigator.pop(context, "返回值"),child: const Text("返回"),)],),),),);}
}
2.2 RouteTestRoute

返回到该页面时,调试模式下打印上个页面携带的参数

class RouteTestRoute extends StatelessWidget {const RouteTestRoute({super.key});Widget build(BuildContext context) {return Scaffold(appBar: AppBar(backgroundColor: Theme.of(context).colorScheme.inversePrimary,title: const Text("路由传值"),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[ElevatedButton(onPressed: () async {// 打开TipRoute,并等待返回结果var result = await Navigator.push(context,MaterialPageRoute(builder: (context) {//路由参数return const TipRoute(text: "提示");}));// 是否为调试模式,是的话为true,不是的话为falseif (kDebugMode) {print("路由返回值:$result");}},child: const Text("打开提示页")),// ElevatedButton(//   onPressed: () {//     Navigator.push(context, MaterialPageRoute(builder: (context) {//       return const MyHomePage(title: "主页");//     }));//   },//   child: const Text("返回主页"),// )])));}
}

3、路由命名

我们可以通过给路由起一个名字,通过这个名字直接打开路由,这使得路由管理更加直观、简单。

3.1 路由表

使用命名路由的前提是提供并注册一个路由表,为名字与路由组件提供对应关系,注册路由表的过程就是为路由起一个名字

  • 定义:Map<String, WidgetBuilder> routes;

它是一个Map,Key为路由的名字,是一个字符串;

value是builder回调函数,用于生成对应路由的Widget;

应用会根据路由名字在路由表中查到对应的WidgetBuilder回调函数,然后调用该回调函数生成Widget并返回。

3.2 注册路由表

使用inititalRoute设置初始路由,并使用后routes注册路由表。更改后要热重载一下,避免页面报错。

class MyApp extends StatelessWidget {/* 声明了一个常量构造函数,它使得Flutter在编译时就确定MyApp对象的结构,而不是在运行时动态创建。这可以提升一定性能,在编译时优化常量对象的创建过程,并且在多个地方使用同一个常量对象时可以减少内存使用。*/const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(// 应用名称title: 'Flutter Demo',initialRoute: "/",  // 初始路由// 主题设置theme: ThemeData(// 主题颜色colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),// 是否使用Material 3的设计规范useMaterial3: true,),// 注册路由表routes: {"/": (context) => const MyHomePage(title: 'Flutter Demo Home Page'),  // 主页路由"new_page": (context) => const NewRoute(),  // 新路由},// 应用首页路由// home: const MyHomePage(title: 'Flutter Demo Home Page'),);}
}
3.3 通过路由名打开新页面

通过路由名打开新路由有两种方式:

  • Navigator.pushNamed:它是最常用的导航发生它允许通过指定的名称打开一个新页面,适合在已经注册名称的情况下使用;
  • Navigator.pushNamedAndRemoveUntil:除了导航到指定的路由外,还会移除直到目标路由的所有页面,非常适合导航到新页面时清除所有中间的页面历史,比如登录后的主页面导航。
// 示例
ElevatedButton(style: ButtonStyle(foregroundColor: WidgetStateProperty.all(Colors.cyan)),onPressed: () {Navigator.pushNamed(context, "new_page");// Navigator.push(context, MaterialPageRoute(builder: (context) {//   return const NewRoute();// }));},child: const Text("示例路由")),

更改示例路由的跳转方式,点击热重载,点击示例路由发现依然可以跳转新路由界面。

3.4 命名路由参数传递
3.4.1 传递参数

修改按钮点击的回调函数,在通过名字访问路由时传递一个arguments值。

ElevatedButton(style: ButtonStyle(foregroundColor: WidgetStateProperty.all(Colors.cyan)),onPressed: () {// 直接打开路由// Navigator.pushNamed(context, "new_page");// 打开路由时传递参数Navigator.of(context).pushNamed("new_page", arguments: "路由参数");// Navigator.push(context, MaterialPageRoute(builder: (context) {//   return const NewRoute();// }));},child: const Text("示例路由")),
3.4.2 接收参数

在名字对应的路由中接收参数并将参数打印在控制台上。

// 新路由示例
class NewRoute extends StatelessWidget {const NewRoute({super.key});Widget build(BuildContext context) {// 获取路由参数var args = ModalRoute.of(context)?.settings.arguments;if (kDebugMode) {print(args);}return Scaffold(appBar: AppBar(title: const Text("新页面"),),body: const Center(child: Text("新路由"),),);}
}
3.4.3 适配

在TipRoute类中,我们通过Navigator.pop(context, “返回值”)将参数传递给上一个页面,在不改变TipRoute源码的情况下适配并将该路由命名。

Widget build(BuildContext context) {return MaterialApp(// 省略无关代码...// 提示页路由"tip2": (context){// 获取传递的参数final arguments  = ModalRoute.of(context)?.settings.arguments;final text = arguments is String ? arguments : '默认文本';return TipRoute(text: text);},},// 应用首页路由// home: const MyHomePage(title: 'Flutter Demo Home Page'),);}
}

RouteTestRoute类直接修改按钮回调函数返回默认文本。

class RouteTestRoute extends StatelessWidget {const RouteTestRoute({super.key});Widget build(BuildContext context) {// 省略无关代码...ElevatedButton(onPressed: () async {Navigator.of(context).pushNamed("tip2");},

若页面接收传递参数,则显示传递参数。

// 新路由示例
class NewRoute extends StatelessWidget {// 省略无关代码...return Scaffold(appBar: AppBar(title: const Text("新页面"),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[ElevatedButton(onPressed: () {Navigator.of(context).pushNamed("tip2", arguments: args);},child: const Text("新路由"))],)),);}
}
3.5 路由生成钩子

假如我们要判断用户是否登录,每打开一个路由页都进行一次判断很麻烦,当Navigator.pushNamed打开命名路由时,如果指定的路由名在路由表中已注册,则会调用路由表中的builder函数来生成路由组件;如果没有注册,则会调用onGenerateRoute来生成路由,回调签名如为:Route< dynamic > onGenerateRoute(RouteSettings settings),有了onGenerateRoute回调,就可以十分容易的控制页面权限了,我们不使用路由表,而是提供一个onGenerateRoute回调,在该回调中进行统一的权限控制。

  // // 注册路由表// routes: {//   // 主页路由//   "/": (context) => const MyHomePage(title: 'Flutter Demo Home Page'),//   // 新路由//   "new_page": (context) => const NewRoute(),//   // 提示页路由//   "tip2": (context) {//     // 获取传递的参数//     final arguments = ModalRoute.of(context)?.settings.arguments;//     final text = arguments is String ? arguments : '默认文本';//     return TipRoute(text: text);//   },// },// 使用onGenerateRoute管理路由onGenerateRoute: (RouteSettings settings) {return MaterialPageRoute(builder: (context) {if (settings.name == "/") {return const MyHomePage(title: 'Flutter Demo Home Page');} else if (settings.name == "new_page") {return const NewRoute();} else if (settings.name == "tip2") {// 获取传递的参数final arguments = ModalRoute.of(context)?.settings.arguments;final text = arguments is String ? arguments : '默认文本';return TipRoute(text: text);}// 如果没有匹配路由则返回默认页面return const MyHomePage(title: 'Flutter Demo Home Page');});},

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/450752.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1997-2022年各省农作物总播种面积数据(无缺失)

1997-2022年各省农作物总播种面积数据 1、时间&#xff1a;1997-2022年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;农作物总播种面积(千公顷) 4、范围&#xff1a;31省 5、缺失情况&#xff1a;无缺失 6、指标解释&#xff1a;农作物播种面积指农业生…

PCL 点云配准-改进的RANSAC算法(粗配准)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 计算FPFH特征 2.1.2 RANSAC配准 2.1.3 可视化点云 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff0…

基于SSM高校课程评价的设计

教师账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;指标信息管理&#xff0c;课程信息管理&#xff0c;教师自评管理 学生账号功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;课程信息管理&#xff0c;学生评价管理 开发系统&#xff1a;…

不坑盒子在哪儿下载?

不坑盒子是一款Office办公软件的插件&#xff0c;支持MicroSoft Office和WPS的三件套&#xff08;Word、Excel、PPT&#xff09;。 可以为你的Office软件增加数百个实用功能&#xff0c;比如&#xff1a;自动排版、智能写作、仿手写、全文加拼音、稿子模板、一键删除、数据分发…

SAP物料凭证报表字段调整

业务场景&#xff1a; 报表MB51的输入和输出字段调整&#xff1a; 输入&#xff08;选择界面&#xff09; 输出界面 可以看到在这是没有布局调整的 后台路径&#xff1a; SPRO-物料管理-库存管理和实际库存-报表-定义物料凭证列表的字段选择 事务码&#xff1a;SM30-V_MMI…

docker构建jar镜像

文章目录 构建 DockerFile将jar包上传到创建的目录当中在目录中创建 Dockerfile 文件构建镜像创建并启动容器说明 构建 DockerFile [root192 /]# mkdir my [root192 /]# cd my [root192 my]# 将jar包上传到创建的目录当中 在目录中创建 Dockerfile 文件 vi Dockerfile FROM …

MFC工控项目实例二十四模拟量校正值输入

承接专栏《MFC工控项目实例二十三模拟量输入设置界面》 对模拟量输入的零点校正值及满量程对应的电压值进行输入。 1、在SenSet.h文件中添加代码 #include "BtnST.h" #include "ShadeButtonST.h"/ // SenSet dialogclass SenSet : public CDialog { // Co…

RPC通讯基础原理

1.RPC&#xff08;Remote Procedure Call&#xff09;概述 RPC是一种通过网络从远程计算机上调用程序的技术&#xff0c;使得构建分布式计算更加容易&#xff0c;在提供强大的远程调用能力时不损失本地调用的语义简洁性&#xff0c;提供一种透明调用机制&#xff0c;让使用者不…

Leetcode 跳跃游戏 二

核心任务是找出从数组的起点跳到终点所需的最小跳跃次数。 这段代码解决的是“跳跃游戏 II”&#xff08;Leetcode第45题&#xff09;&#xff0c;其核心任务是找出从数组的起点跳到终点所需的最小跳跃次数。 class Solution {public int jump(int[] nums) {//首先处理特殊情…

【文化课学习笔记】【化学】选必三:同分异构体的书写

【化学】选必三&#xff1a;同分异构体的书写 如果你是从 B 站一化儿笔记区来的&#xff0c;请先阅读我在第一篇有机化学笔记中的「读前须知」(点开头的黑色小三角展开)&#xff1a;链接 链状烃的取代和插空法 取代法 一取代物 甲烷、乙烷、丙烷、丁烷的种类 甲烷&#xff1a;只…

【AAOS】Android Automotive 14模拟器源码下载及编译

源码下载 repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r20 repo sync -c --no-tags --no-clone-bundle 源码编译 source build/envsetup.sh lunch sdk_car_x86_64-trunk_staging-eng make -j8 运行效果 emualtor Home All apps …

计算机是如何输入存储输出汉字、图片、音频、视频的

计算机是如何输入存储输出汉字、图片、音频、视频的 为了便于理解&#xff0c;先了解一下计算机的组成。 冯诺依曼计算机的五大组成部分。分别是运算器、控制器、存储器、输入设备和输出设备。参见下图&#xff1a; 一、运算器 运算器又称“算术逻辑单元”&#xff0c;是计算…

Android Camera2在textureView中的预览和拍照

Camera2预览和拍照 1、Camera2相机模型2、Camera2的重要类3、Camera2调用流程4、Camera2调用实现 1)定义TextureView作为预览界面2)设置相机参数3)开启相机4)开启相机预览5)实现PreviewCallback6)拍照 1、Camera2相机模型 解释上诉示意图&#xff0c;假如想要同时拍摄两张不同…

图像及视频的基本操作

文章目录 一、认识计算机中的图像二、图像数据的读取三、数据读取-视频四、图像的其他操作 一、认识计算机中的图像 一张彩色图片是由很多个像素点组合而成的&#xff0c;而一个像素点是由R G B三个通道组成。RGB代表红色&#xff08;Red&#xff09;、绿色&#xff08;Green&a…

【远程监控新体验】OpenObserve结合内网穿透无公网IP远程访问全攻略

文章目录 前言1. 安装Docker2. Docker镜像源添加方法3. 创建并启动OpenObserve容器4. 本地访问测试5. 公网访问本地部署的OpenObserve5.1 内网穿透工具安装5.2 创建公网地址6. 配置固定公网地址前言 本文主要介绍如何在Linux系统使用Docker快速本地化部署OpenObserve云原生可观…

MacOS RocketMQ安装

MacOS RocketMQ安装 文章目录 MacOS RocketMQ安装一、下载二、安装修改JVM参数启动关闭测试关闭测试测试收发消息运行自带的生产者测试类运行自带的消费者测试类参考博客&#xff1a;https://blog.csdn.net/zhiyikeji/article/details/140911649 一、下载 打开官网&#xff0c;…

并发-线程

1, 线程 线程(thread)也是并发的一种形式&#xff0c;线程是比进程更小的活动单位&#xff0c;一个进程中可以有多个线程&#xff0c;线程是进程内部的一个执行分支。 一个进程刚开始时只有一个线程(称之为主线程)&#xff0c;后续的代码中可以创建新的线程&#xff0c;可以指…

git提交到github个人记录

windows下git下载 1.进入git官网https://git-scm.com/downloads/win 一直默认选项即可 2.在settings中SSH and GPG keys中Add SSH key 3.选择git cmd git使用 1.配置用户名&#xff0c;和邮箱 git config --global user.email "youexample.com" git config --g…

aws(学习笔记第六课) AWS的虚拟私有,共有子网以及ACL,定义公网碉堡主机子网以及varnish反向代理

aws(学习笔记第六课) AWS的虚拟私有&#xff0c;共有子网以及ACL&#xff0c;定义公网碉堡主机子网以及varnish反向代理 学习内容&#xff1a; AWS的虚拟私有&#xff0c;共有子网以及ACL定义公网碉堡主机子网&#xff0c;私有子网和共有子网以及varnish反向代理 1. AWS的虚拟…

深入理解WPF中的命令机制

Windows Presentation Foundation&#xff08;WPF&#xff09;是微软推出的一种用于构建桌面客户端应用程序的技术。它被认为是现代Windows应用程序的基础&#xff0c;具有强大的图形和媒体处理能力。在WPF中&#xff0c;“命令”是一个重要的概念&#xff0c;它为应用程序开发…