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

Flutter 组件集录 | InheritedNotifier 内置状态管理组件


theme: cyanosis

1. 前言

在上一篇 《Flutter 知识集锦 | 监听与通知 ChangeNotifier》 中,我们介绍了 ChangeNotifier 对象通知监听者的能力。并通过一个简单的模拟下载进度案例,介绍了它的使用方式:

| 案例演示 | 监听-通知关系 | | --- | --- | | 184.gif | 未标题-1.png |

上一节通过全局变量来维护 ProgressValueNotifier 类型的 progress 对象,让它可以在代码中的任何位置被访问到。本文将介绍 InheritedNotifier 组件的使用,给可监听对象一个 归宿

image.png


2. InheritedNotifier 组件的使用

本文代码收录在 FlutterUnit 中,可在仓库中查看完整代码:

lib/awesome/listenable/changenotifier02

使用 InheritedNotifier 时需要定义一个子类,该类的功能之一是让数据在子树中共享数据。其中泛型便是上一篇中的 ProgressValueNotifier 可监听对象。

如下所示,定义 DownloadDataScope 类型,在构造中传入可监听对象和子组件,然后定义两个静态方法 ofread 获取存储的数据。获取的方式是通过上下文向上查询特定类型的组件。

```dart class DownloadDataScope extends InheritedNotifier {

const DownloadDataScope({super.key, required super.child,super.notifier});

static ProgressValueNotifier of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType ()!.notifier!; }

static ProgressValueNotifier read(BuildContext context) { return context.getInheritedWidgetOfExactType ()!.notifier!; } } ```

然后在想要更新数据的上层节点,套上 DownloadDataScope 组件,这样数据就可以在子树节点中被共享:

image.png


使用时就非常方便,通过静态方法 of 根据上下文获取可监听对象即可。此时称: DetailProgressView 依赖了该可监听的通知器,那么在可监听对象发出通知时,就会自动通知该组件,触发 build 方法。
可以看到 DetailProgressView 此时可以是 StatelessWidget , 但依然会被通知,从而重新构建。这是一种非 State#setState 更新状态的方式。

image.png


另外,如果只是想访问数据,不想在可监听对象发生通知时,被触发更新。可以通过 read 静态方法,底层通过 getInheritedWidgetOfExactType 查询类型。比如这里主页面只想访问可监听对象,来更新数据,就可以只通过 read 来访问:

image.png

这样,通过 InheritedNotifier 组件,既可以实现数据的共享,又可以触发更新,通知需要根据数据变化的组件。相比于直接使用 ChangeNotifier 组件,省去了添加监听和移除监听的流程。对于需要共享的状态数据管理,是非常实用的。


3. InheritedNotifier 源码分析

InheritedNotifier 是一个抽象类,使用时需要进行派生,它本身继承自 InheritedWidget ,也就是说其持有的数据可以在子树中,通过上下文被访问。它有一个泛型,该类型需要继承自 Listenable ,其中 notifier 的类型是 T? 也就是一个可监听对象。

```dart abstract class InheritedNotifier extends InheritedWidget { const InheritedNotifier({ super.key, this.notifier, required super.child, });

final T? notifier;

@override bool updateShouldNotify(InheritedNotifier oldWidget) { return oldWidget.notifier != notifier; }

@override InheritedElement createElement() => _InheritedNotifierElement (this); } ```

InheritedNotifier 神奇的地方在于:使用了 of 获取数据的组件,在可监听对象发生通知时会触发重新构建。使用这里似乎没有什么核心代码,可以触发组件更新。我们仔细看一下,可以发现这里重写了 createElement 方法,所以说,魔法就在这里:

如下所示,在 _InheritedNotifierElement 构造时,会监听 notifier 触发 _handleUpdate。其中会将 _dirty 置为 false ,触发 markNeedsBuild 方法。了解 Flutter 框架的都知道 State#setState 本质上也就是触发了持有 Element 的 markNeedsBuild 方法。

image.png

也就是说,这里当可监听对象发生变化时,会通知 InheritedNotifier 对应的元素进行重新构建,触发 build 方法。如果 _dirty 为 true ,会触发 notifyClients 方法,通知依赖者:

image.png

dart @override void notifyClients(InheritedNotifier<T> oldWidget) { super.notifyClients(oldWidget); _dirty = false; }


这里有个前置知识,在《 Flutter 渲染机制 - 聚沙成塔》 第10章中,介绍过 InheritedElement 会维护依赖元素的映射,进行通知。凡是调用 dependOnInheritedWidgetOfExactType 的元素,都会被加入到映射中:

image.png

触发 notifyClients 时,将会通知元素映射中的元素触发 didChangeDependencies 。如下所示,此时其中是 HomeProgressView 对应的元素:

image.png

也就是说,接下来 HomeProgressView 对应的元素触发 didChangeDependencies,其中调用了 markNeedsBuild ,也就是说该元素被标脏,将在之后被重新构建。这就是 HomeProgressView 在可监听对象变化时,更新界面的根本原因。

image.png


4. InheritedNotifier 源码分析

InheritedNotifier 组件在元素的层级处理了依赖者界面的更新,既可以共享数据,又可以触发更新通知,是一种比较小巧的状态管理方式。你在官方的很多案例中,都可以看到用 InheritedNotifier 管理共享状态的案例。那么本文就到这里,谢谢观看 ~

相关文章:

Flutter 组件集录 | InheritedNotifier 内置状态管理组件

theme: cyanosis 1. 前言 在上一篇 《Flutter 知识集锦 | 监听与通知 ChangeNotifier》 中&#xff0c;我们介绍了 ChangeNotifier 对象通知监听者的能力。并通过一个简单的模拟下载进度案例&#xff0c;介绍了它的使用方式&#xff1a; | 案例演示 | 监听-通知关系 | | --- | …...

NOIP2023模拟10联测31 涂鸦

题目大意 有一面由 n m n\times m nm个格子组成的墙&#xff0c;每个格子要么是黑色&#xff0c;要么是白色。你每次将会进行这样的操作&#xff1a;等概率随机选择一个位置 ( x , y ) (x,y) (x,y)和一个颜色 c c c&#xff08;黑色或白色&#xff09;&#xff0c;&#xff0…...

【Python基础知识一】基本语法、常用数据类型等

Python基础知识&#xff1a; 1 标识符&#xff08;Identifier&#xff09;2 关键字/保留字&#xff08;Keyword&#xff09;3 引号4 编码5 输入输出6 行与缩进7 多行语句8 注释9 数据类型9.1 数字(Number)类型9.2 变量&#xff08;variate&#xff09;9.3 字符串&#xff08;St…...

听听ChatGPT对IT行业的发展和就业前景的看法

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏:PYTHON学习系列专栏&#x1f4ab;"没有罗马,那就自己创造罗马~" 目录 (1)判断素数 写法1: 写法2: (2)计算1-100的偶数之和 写法1: 写法2: (3)计算1-100的奇数之和 (4)多层循环 IT行业哪个方向比较…...

〖程序员的自我修养 - 认知剖析篇⑤〗- 选择前端还是后端?

人之所以会觉得迷茫,本质上是欠缺对自己的一个控制力、识别庞杂信息、去伪存真的独立思考与认知能力。 说明:该文属于 程序员的自我修养 专栏,购买任意白宝书体系化专栏可加入易编程社区,早鸟价订阅模式除外。福利:加入社区的小伙伴们,除了可以获取博主所有付费专栏的阅读…...

Rust语言初步

文章目录 安装与测试变量条件语句和函数数组和元组循环 安装与测试 可以从官网直接下载。下载rustup-init并运行之后&#xff0c;会打开命令行&#xff0c;选1默认安装&#xff0c;然后不出意外就安装完了。 安装完成后按照惯例查看一下版本&#xff0c;如不报错就算成功。 …...

BIMILLC算法源码解析

论文链接&#xff1a;https://arxiv.org/abs/1607.02533 源码出处&#xff1a;https://github.com/Harry24k/adversarial-attacks-pytorch/tree/master 源码 import torch import torch.nn as nnfrom ..attack import Attackclass BIM(Attack):r"""BIM or iter…...

Android STR研究之五

前言&#xff1a; 在前四篇中初步介绍了开机流程&#xff0c;STR流程&#xff0c;唤醒流程&#xff0c;这里讲下STR的问题点 Android STR研究之一-CSDN博客 Android STR研究之二-CSDN博客 Android STR研究之三-CSDN博客 Android STR研究之四-CSDN博客 问题1&#xff1a;进入STR…...

python3+requests接口自动化测试实例详细操作

前段时间由于公司测试方向的转型&#xff0c;由原来的web页面功能测试转变成接口测试&#xff0c;之前大多都是手工进行&#xff0c;利用postman和jmeter进行的接口测试&#xff0c;后来&#xff0c;组内有人讲原先web自动化的测试框架移驾成接口的自动化框架&#xff0c;使用的…...

在Node.js中,什么是中间件(middleware)?它们的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

当函数参数为一级指针,二级指针

当函数参数为一级指针&#xff0c;二级指针 在讲述内容之前&#xff0c;先讲四点重要知识 1.当传入参数时&#xff0c;函数形参会立即申请形参的内存空间&#xff0c;函数执行完毕后&#xff0c;形参的内存空间立即释放掉。 1.指针是存放其他变量地址的变量。指针有自己的内…...

Hydra post登录框爆破

文章目录 无token时的Hydra post登录框爆破带Token时的Hydra post登录框爆破 无token时的Hydra post登录框爆破 登录一个无验证码和token的页面&#xff0c;同时抓包拦截 取出发送数据包&#xff1a;usernameadb&password133&submitLogin 将用户名和密码替换 userna…...

阿里云推出AI编程工具“通义灵码“;生成式 AI 入门教程 2

&#x1f989; AI新闻 &#x1f680; 阿里云推出AI编程工具"通义灵码"&#xff0c;支持多种语言及实时续写功能 摘要&#xff1a;阿里云推出了一款名为"通义灵码"的AI编程工具&#xff0c;支持多种主流编程语言&#xff0c;包括Java、Python、Go等。该工…...

使用Qt Installer Framework将自己的程序打包成安装包程序

使用Qt Installer Framework将自己的程序打包成安装包程序 制作安装包程序就是将自己的程序打包成一个可执行的exe&#xff0c;双击之后进行安装。 1. 在制作安装包程序之前需要安装qt官方提供的安装包制作工具Qt Installer Framework 去qt官方网址&#xff0c;下载对应的 Q…...

逆袭Flutter? Facebook 发布全新跨平台引擎 Hermes!

Facebook 于前日发布了新的 JavaScript 引擎&#xff1a;Hermes&#xff0c;专注于提高 React Native 应用的性能&#xff0c;并且在市面上那些内存较少、存储速度较慢且计算能力低下的移动设备上都有良好的表现。但是不是为了追赶Flutter&#xff1f;这块作者没有说明。 移动应…...

c++ 互斥锁使用详解 lock_guard

c 互斥锁使用详解 std::mutex 用于保护共享资源&#xff0c;防止多个线程同时修改共享资源而引发竞争条件。 成员函数 lock&#xff1a;锁定互斥&#xff0c;若互斥不可用则阻塞。try_lock&#xff1a;尝试锁定互斥&#xff0c;若互斥不可用则返回。unlock&#xff1a;解锁…...

【快速解决】Android Button页面跳转功能

目录 让我们直接开始 第一步&#xff1a;先建立一个新的activity ​编辑 第二步&#xff1a;打开第一个页面的Java文件MainActivity 方法一&#xff1a;直接跳转功能如下&#xff1a; 方法二&#xff1a;输入密码才能进行跳转功能如下&#xff1a; 需要注意的地方 结语 让…...

C语言 pthread_create

备注void *&#xff0c;最好添加返回值 原因&#xff1a;在实践中&#xff0c;虽然你的函数可能不需要返回任何值&#xff0c;但为了与 pthread_create 函数的预期函数指针格式相匹配&#xff0c;最好遵守函数指针所需的返回类型。这是一种良好的编程实践&#xff0c;确保你的代…...

前端uniapp提交表单调用接口方法最新

目录 源码1源码2最后 源码1 <template><view class"my-add-bank-card"><!-- name"bank_name" form表单提交的input里面一定要加name绑定要传的参数 name"bank_name" type"text" v-model"address.bank_name"…...

OpenFeign的简单介绍和功能实操

前言 本文主要做一下OpenFeign的简单介绍和功能实操&#xff0c;实操主要是OpenFeign的超时和重试&#xff0c;在阅读本文章前&#xff0c;请完成《Nacos 注册中心介绍与实操》内的Nacos多模块生产消费者项目 什么是OpenFeign OpenFeign全名Spring Cloud OpenFeign&#xff…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...