当前位置: 首页 > news >正文

Flutter笔记:路由观察者

Flutter系列
路由观察者

作者李俊才 (jcLee95):https://blog.csdn.net/qq_28550263
邮箱 :291148484@163.com
本文地址:https://blog.csdn.net/qq_28550263/article/details/134572181



1. 概述

路由观察者(Route Observer)是一个监听路由(页面)变化的工具。在Flutter应用中,我们经常需要监听路由的变化,例如当用户从一个页面跳转到另一个页面时,我们可能需要执行一些操作,如数据统计、页面切换动画等,这时就需要用到路由观察者。

路由观察者的定义:路由观察者是一个抽象类,它定义了一些方法,这些方法可以在路由发生变化时被调用。我们可以通过继承路由观察者类并实现这些方法,来创建自己的路由观察者。

路由观察者的作用:路由观察者的主要作用是监听路由的变化,当路由发生变化时,路由观察者的相应方法会被调用,我们可以在这些方法中执行需要的操作。

路由观察者的使用场景:路由观察者可以用于各种需要监听路由变化的场景,例如数据统计、页面切换动画、用户行为跟踪等。

总的来说,路由观察者是Flutter中一个非常重要的工具,它可以帮助我们更好地理解和控制路由的变化。

2. 路由观察者的创建和使用

2.1 NavigatorObserver类的介绍

在Flutter中,路由观察者是通过继承NavigatorObserver类来创建的。NavigatorObserver是一个抽象类,它定义了一些方法,这些方法会在路由发生变化时被调用。例如,didPush方法会在新的路由被推送到导航器时被调用,didPop方法会在路由从导航器中弹出时被调用。

2.2 创建一个NavigatorObserver的子类

要创建一个路由观察者,我们需要创建一个NavigatorObserver 的子类,并实现它的方法。下面是一个简单的例子:

class MyRouteObserver extends NavigatorObserver {void didPush(Route route, Route previousRoute) {super.didPush(route, previousRoute);print('didPush ${route.settings.name}');}void didPop(Route route, Route previousRoute) {super.didPop(route, previousRoute);print('didPop ${route.settings.name}');}
}

在这个例子中,我们创建了一个名为 MyRouteObserver 的路由观察者,它会在路由被推送和弹出时打印路由的名称。

2.3 将路由观察者添加到MaterialApp或WidgetsApp

创建了路由观察者后,我们需要将它添加到 MaterialAppWidgetsApp 中,这样它才能监听到路由的变化。这可以通过设置navigatorObservers 属性来实现:

void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {final MyRouteObserver _myRouteObserver = MyRouteObserver();Widget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',navigatorObservers: [_myRouteObserver],home: MyHomePage(),);}
}

在这个例子中,我们创建了一个 MyRouteObserver 的实例,并将它添加到了 MaterialApp 的navigatorObservers中。这样,MyRouteObserver 就能监听到所有路由的变化了。

3. 路由观察者的方法

路由观察者的方法主要包括 didPushdidPopdidRemovedidReplace 等。下面我们来详细介绍这些方法。

3.1 didPush

didPush 方法会在新的路由被推送到导航器时被调用。它有两个参数:routepreviousRoute,分别表示新推送的路由和之前的路由。

使用场景:当我们需要在新的路由被推送时执行一些操作时,可以在didPush方法中实现。

3.2 didPop

didPop 方法会在路由从导航器中弹出时被调用。它的参数和 didPush 方法相同。

使用场景:当我们需要在路由被弹出时执行一些操作时,可以在didPop方法中实现。

3.3 didRemove

didRemove 方法会在路由被从导航器中移除时被调用。它有两个参数:routepreviousRoute ,分别表示被移除的路由和之前的路由。

使用场景:当我们需要在路由被移除时执行一些操作时,可以在didRemove方法中实现。

3.4 didReplace

didReplace 方法会在一个路由被另一个路由替换时被调用。它有两个参数:newRoute 和 oldRoute,分别表示新的路由和被替换的路由。

使用场景:当我们需要在路由被替换时执行一些操作时,可以在didReplace方法中实现。

下面是一个使用这些方法的例子:
在这个例子中,我们在每个方法中都打印了相关的信息,这样我们就可以清楚地看到路由的变化。

class MyRouteObserver extends NavigatorObserver {void didPush(Route route, Route previousRoute) {super.didPush(route, previousRoute);print('didPush ${route.settings.name}');}void didPop(Route route, Route previousRoute) {super.didPop(route, previousRoute);print('didPop ${route.settings.name}');}void didRemove(Route route, Route previousRoute) {super.didRemove(route, previousRoute);print('didRemove ${route.settings.name}');}void didReplace({Route newRoute, Route oldRoute}) {super.didReplace(newRoute: newRoute, oldRoute: oldRoute);print('didReplace ${oldRoute.settings.name} with ${newRoute.settings.name}');}
}

4. 路由观察者的应用

路由观察者在 Flutter 应用中有很多实际的应用场景,例如用于用户行为跟踪,页面切换动画等。

4.1 用户行为跟踪

在很多应用中,我们需要跟踪用户的行为,例如用户打开了哪些页面,停留在每个页面的时间等。这时,我们可以使用路由观察者来实现。

当用户打开一个新的页面时,didPush 方法会被调用,我们可以在这个方法中记录用户打开这个页面的时间;当用户关闭一个页面时,didPop 方法会被调用,我们可以在这个方法中记录用户关闭这个页面的时间。通过这种方式,我们就可以跟踪用户在每个页面的停留时间。

4.2 页面切换动画

在一些应用中,我们希望在页面切换时有一些特殊的动画效果。这时,我们也可以使用路由观察者来实现。

我们可以在 didPushdidPop 方法中添加动画效果。例如,当用户打开一个新的页面时,我们可以在 didPush 方法中添加一个淡入效果;当用户关闭一个页面时,我们可以在 didPop 方法中添加一个淡出效果。

下面是一个使用路由观察者来实现用户行为跟踪的例子:

class MyRouteObserver extends NavigatorObserver {void didPush(Route route, Route previousRoute) {super.didPush(route, previousRoute);print('User opened ${route.settings.name}');// 这里我们可以启动一个计时器来跟踪用户在这个页面上停留的时间。}void didPop(Route route, Route previousRoute) {super.didPop(route, previousRoute);print('User closed ${route.settings.name}');// 在这里,我们可以停止计时器,并获得用户在此页面停留的时间。}
}

在这个例子中,我们在 didPushdidPop 方法中分别打印了用户打开和关闭页面的信息,并且提到了如何使用计时器来跟踪用户在每个页面的停留时间。

5. 路由观察者的限制和注意事项

虽然路由观察者是一个非常强大的工具,但在使用过程中也有一些限制和需要注意的事项。

5.1 限制

仅仅监听 Navigator 进行的路由变化

  1. 路由观察者只能监听到通过 Navigator 进行的路由变化,如果路由变化是通过其他方式(例如直接修改组件的状态)进行的,那么路由观察者是无法监听到的。

PopScope

  1. 路由观察者的方法是在路由变化后被调用的,因此它不能阻止路由的变化。如果你需要在路由变化前进行一些操作(例如询问用户是否确定要离开当前页面),那么你需要使用其他的方法,例如 PopScopeWillPopScope 已经被废弃,使用PopScope替代)。
    关于 PopScope 这里补充一个案例分析:
import 'package:flutter/material.dart';void main() => runApp(const NavigatorPopHandlerApp());class NavigatorPopHandlerApp extends StatelessWidget {const NavigatorPopHandlerApp({super.key});Widget build(BuildContext context) {return MaterialApp(// 设置初始路由为 '/home'initialRoute: '/home',// 定义路由表routes: <String, WidgetBuilder>{'/home': (BuildContext context) => const _HomePage(),'/two': (BuildContext context) => const _PageTwo(),},);}
}
class _HomePage extends StatefulWidget {const _HomePage();State<_HomePage> createState() => _HomePageState();
}// 首页的状态组件
class _HomePageState extends State<_HomePage> {Widget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text('Page One'), // 显示 "Page One" 文字TextButton(onPressed: () {Navigator.of(context).pushNamed('/two'); // 点击按钮后跳转到第二个页面},child: const Text('Next page'), // 显示 "Next page" 文字),],),),);}
}
// 第二个页面的组件
class _PageTwo extends StatefulWidget {const _PageTwo();State<_PageTwo> createState() => _PageTwoState();
}// 第二个页面的状态组件
class _PageTwoState extends State<_PageTwo> {// 显示一个对话框,询问用户是否确定离开void _showBackDialog() {showDialog<void>(context: context,builder: (BuildContext context) {return AlertDialog(title: const Text('Are you sure?'), // 对话框标题content: const Text('Are you sure you want to leave this page?', // 对话框内容),actions: <Widget>[TextButton(style: TextButton.styleFrom(textStyle: Theme.of(context).textTheme.labelLarge,),child: const Text('Nevermind'), // "Nevermind" 按钮onPressed: () {Navigator.pop(context); // 点击后关闭对话框},),TextButton(style: TextButton.styleFrom(textStyle: Theme.of(context).textTheme.labelLarge,),child: const Text('Leave'), // "Leave" 按钮onPressed: () {Navigator.pop(context); // 点击后关闭对话框Navigator.pop(context); // 并返回上一个页面},),],);},);}Widget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text('Page Two'), // 显示 "Page Two" 文字PopScope(canPop: false,onPopInvoked: (bool didPop) {if (didPop) {return;}_showBackDialog(); // 当用户尝试离开时,显示对话框},child: TextButton(onPressed: () {_showBackDialog(); // 点击按钮后显示对话框},child: const Text('Go back'), // 显示 "Go back" 文字),),],),),);}
}

这段代码是Flutter官方给出的一个案例,它包含两个页面,用户可以在这两个页面之间导航。当用户尝试离开第二个页面时,会弹出一个对话框询问用户是否确定离开。

5.2 注意事项

  1. 在使用路由观察者时,需要注意不要在路由观察者的方法中进行过于复杂的操作,因为这可能会影响到路由的性能。如果需要进行复杂的操作,建议在另一个异步任务中进行。

  2. 在使用路由观察者时,需要注意正确地管理路由观察者的生命周期。如果一个路由观察者被销毁了,但是你仍然试图在它的方法中访问一些资源,那么可能会导致错误

  3. 在使用路由观察者时,需要注意处理好异常。因为路由观察者的方法是在路由变化后被调用的,如果在这些方法中发生了异常,那么可能会导致应用崩溃。

相关文章:

Flutter笔记:路由观察者

Flutter系列 路由观察者 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/134572181 目 录 1. 概述2. 路由…...

【驱动】串口驱动分析(三)-serial driver

简介 前两节我们介绍串口驱动的框架和tty core部分。这节我们介绍和硬件紧密相关的串口驱动部分。 UART驱动部分依赖于硬件平台&#xff0c;而TTY驱动和具体的平台无关。虽然UART部分依赖于平台&#xff0c;但是不管是哪个硬件平台&#xff0c;驱动的思路都是一致的&#xff…...

(C++20) constinit常量初始化

文章目录 由来constinit 常量初始化常量初始化 ! 初始化常量初始化声明静态存储对象非初始化声明thread_local END 由来 在C多文件编译中会出现一个常见的问题&#xff0c;叫做静态初始化顺序问题。Static Initialization Order Fiasco。 比如现在有两个文件&#xff0c;其中…...

python实现获取aws route53域名信息

最近由于工作原因接触到aws的服务&#xff0c;我需要实时获取所有的域名信息&#xff0c;用于对其进行扫描&#xff0c;因此写了一个自动化爬取脚本 给需要的人分享。 1.基础准备 代码环境&#xff1a;python3 第三方库&#xff1a;boto3 &#xff08;安装方法pip install…...

Linux_Linux终端常用快捷键

Linux命令行核心常用快捷键是一些在终端中使用的快捷键组合&#xff0c;用于提高命令行操作的效率。下面是这些快捷键的原理详细解释、使用场景解释 Ctrl A &#xff1a;将光标移动到命令行的开头。这个快捷键的原理是发送一个控制序列到终端&#xff0c;告诉终端将光标移动到…...

Neo4j 数据库管理 数据备份与恢复(头歌)

文章目录 第1关&#xff1a;数据备份与恢复任务描述相关知识数据备份数据导入 编程要求测试说明答案测试前准备Cypher 代码数据备份与导入 第1关&#xff1a;数据备份与恢复 任务描述 本关任务&#xff1a;熟练掌握数据备份与恢复。 相关知识 为了完成本关任务&#xff0c;…...

TCP传输的三次握手四次挥手策略

TCP传输的三次握手四次挥手策略如下&#xff1a; 第一次握手&#xff1a;客户端发送一个带有SYN标志的数据包给服务器&#xff0c;并记为SYN_Client。第二次握手&#xff1a;服务器收到SYN_Client后&#xff0c;向客户端发送一个带有SYN和ACK标志的数据包&#xff0c;记为SYN_…...

在gitlab上使用server_hooks

文章目录 1. 前置条件2. Git Hook2.1 Git Hook 分为两部分&#xff1a;本地和远程2.1.1 本地 Git Hook&#xff0c;由提交和合并等操作触发&#xff1a;2.1.2 远程 Git Hook&#xff0c;运行在网络操作上&#xff0c;例如接收推送的提交&#xff1a; 3. 操作步骤3.1 对所有的仓…...

【云原生系列】Kubernetes知识点

目录 概念 基础架构 单master节点 多master节点 组件 Master节点核心组件 其他组件 请求发送流程 插件 核心资源 调度资源 Pod 创建pod组件间调用流程 pod生命周期&#xff1a; 初始化容器 镜像拉取策略 重启策略 钩子函数 探针 探针的实现方式 DownwardAP…...

Hugging-Face报错锦囊(不断更新)

requests.exceptions.SSLError: (MaxRetryError(“HTTPSConnectionPool(host‘huggingface.co’, port443): Max retries exceeded with url: /api/models/bert-base-chinese (Caused by SSLError(SSLCertVerificationError(1, ‘[SSL: CERTIFICATE_VERIFY_FAILED] certificate…...

Redis核心数据结构

目录 五种基础数据结构 string hash list set zset 用zset实现微博热搜 scan遍历 高频问题 五种基础数据结构 string 单个赋值set 批量赋值/取值 msetmget 设置不存在字符串setnx, 如果不存在, 则设置成功返回1, 如果存在返回0, 可以当做分布式锁 删除值 设置过期时…...

Redis 如何批量删除指定前缀的Key

批量删除指定前缀的Key有两中方法&#xff0c;一种是借助 redis-cli&#xff0c;另一种是通过 SCAN 命令来遍历所有匹配前缀的 key&#xff0c;并使用 DEL 命令逐个删除它们。 redis-cli 使用 Redis 自带的 redis-cli 命令行工具&#xff0c;你可以通过以下方式批量删除指定前…...

如何熟练使用vim工具?

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f…...

ClassNotFoundException: org.apache.hive.spark.client.Job

hive使用的是3.13版本&#xff0c;spark是3.3.3支持hadoop3.x hive将engine从mr改成spark&#xff0c;通过beeline执行insert、delete时一直报错&#xff0c;sparkTask rpc关闭&#xff0c; 查看yarn是出现ClassNotFoundException: org.apache.hive.spark.client.Job。 开始…...

《合成孔径雷达成像算法与实现》_使用CS算法对RADARSAT-1数据进行成像

CSA 简介&#xff1a;Chirp Scaling 算法 (简称 CS 算法&#xff0c;即 CSA) 避免了 RCMC 中的插值操作。该算法基于 Scaling 原理&#xff0c;通过对 chirp 信号进行频率调制&#xff0c;实现了对信号的尺度变换或平移。基于这种原理&#xff0c;可以通过相位相乘代替时域插值…...

GCN01——Ubuntu中设置vivado编辑器为vscode

确定vscode位置 在命令行中输入 which code得到文件地址 进入文件夹后可看到&#xff0c;这是个链接文件&#xff0c;不过无所谓&#xff0c;就用这个地址就行 设置Text Editor 打开setting选择右侧text editor 这里说明了如何进行设置 将自己的地址加进去就行 /usr/share…...

Android 11.0 软硬键盘同时使用的兼容(软键盘与内置物理键盘共存)

1.概述 在11.0的系统rom产品定制化开发总,在有些设备上,如果外接了USB扫描枪之类的设备,当插入USB扫描枪以后,然后点击输入调用输入法的时候,没有反应,但是拔掉USB扫描枪以后,输入法又能正常使用,这说明和输入法起冲突了,询问了好多同时,说可能把会把USB扫描枪识别为…...

ARM安全架构——为复杂软件提供保护

目录 一、概述 二、栈溢出和执行权限 三、面向返回的编程ROP 四、面向跳转的编程(JOP) 五、将这些技术应用于实际代码 七、检查你的知识...

提升网页交互体验的秘密武器——防抖和节流

说在前面 在现代Web开发中&#xff0c;提高网页性能是至关重要的。本文介绍了防抖和节流这两种常用的性能优化技术&#xff0c;通过控制函数的执行频率&#xff0c;有效减少不必要的计算和网络请求&#xff0c;从而提升用户体验和页面加载速度。 函数节流 节流是指限制一个函数…...

HX3002入耳检测光感驱动调试-感0x08 寄存器溢出,不变化错误问题解决方法

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群赠送语音信号处理降噪算法,蓝牙耳机音频,DSP音频项目核心开发资料, 读取光感0x08 寄存器溢出,不变化错误问题?原因 原因:没有读取到0x08数据,没有读0x…...

目标检测开源数据

KITTI KITTI数据集下载&#xff08;百度云&#xff09;_kitti数据集百度云-CSDN博客 KITTI数据集下载及解析_kitti bin文件标签-CSDN博客 KITTI 3D目标检测数据集解析&#xff08;完整版&#xff09;_kitti数据集结构-CSDN博客 KITTI数据集简介与使用_kitti数据见一个视频多…...

AI模特换装的前端实现

本文作者为 360 奇舞团前端开发工程师 随着AI的火热发展&#xff0c;涌现了一些AI模特换装的前端工具&#xff08;比如weshop网站&#xff09;&#xff0c;他们是怎么实现的呢&#xff1f;使用了什么技术呢&#xff1f;下文我们就来探索一下其实现原理。 总体的实现流程如下&am…...

git-5

1.GitHub为什么会火&#xff1f; 2.GitHub都有哪些核心功能&#xff1f; 3.怎么快速淘到感兴趣的开源项目 github上面开源项目非常多&#xff0c;为了我们高效率的找到我们想要的资源 根据时间 不进行登录&#xff0c;是没有办法享受到高级搜索中的代码功能的&#xff0c;登录…...

qt 5.15.2压缩和解压缩功能

qt 5.15.2压缩和解压缩功能 主要是添加qt项目文件.pro内容&#xff1a; 这里要先下载quazip的c项目先编译后引入到本项目中/zip目录下 INCLUDEPATH ./zip CONFIG(debug, debug|release) {win32:win32-g: PRE_TARGETDEPS $$PWD/zip/libquazipd.awin32:win32-g: LIBS -L$$PWD…...

thinkphp6出现 htmlentities() expects parameter 1 to be string, array given

为避免出现 XSS 安全问题&#xff0c; thinkphp6默认变量输出都会使用 htmlentities 方法进行转义 输出。 如果不想被转义输出&#xff0c;模板渲染时&#xff0c;需要在变量后面加上 raw方法&#xff0c;如&#xff1a;{$data|raw} 1、出现问题前的代码 PHP代码$this->assi…...

【android开发-03】android中Intent的用法介绍

1&#xff0c;Intent的作用 在Android开发中&#xff0c;Intent的使用非常广泛&#xff0c;包括启动Activity、启动Service、发送广播等。是各组件间交互的一种重要方式&#xff0c;他不仅可以指明当前组件想要执行的动作&#xff0c;还可以在不同组件间传递数据。 Intent可以…...

Java中时间工具详解:java.time包的应用

引言 时间在软件开发中是一个至关重要的概念&#xff0c;而Java自从引入java.time包后&#xff0c;提供了更加强大和灵活的时间处理工具。本文将深入介绍java.time包中的一些常用时间工具&#xff0c;帮助你更好地处理日期和时间的操作。 1. LocalDate - 处理日期 LocalDate…...

mysql 日志分析

程序启动标志 可以直接全局搜索&#xff0c;查看启动了几次 可以看到总共11次&#xff0c;当前是第2次 如何判断mysql是正常关闭&#xff0c;手动启动的 下图中启动之前出现 Shutdown complete打印说明启动之前是正常关闭的...

网络运维与网络安全 学习笔记2023.11.30

网络运维与网络安全 学习笔记 第三十一天 今日目标 实现AP自动注册、配置WLAN业务参数、无线终端通过wifi互访 实现AP自动注册 项目背景 企业内网的大量AP已经通过DHCP的方式获得IP地址 为了实现后期大量AP的统一管理&#xff0c;希望通过AC实现集中控制 在AC设备上&#…...

Perplexity 推出全新大型在线语言模型

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...