ForEach刷新UI机制
官网地址:ForEach
在ArkUI中,提供了ForEach循环语句,用来初始化一个列表数据,我们知道,当ForEach中的数组发生变化时,会引起UI的刷新,但是究竟如何变化,会引起UI怎样的刷新,还需要进一步的去探索其逻辑。
1. ForEach参数和规则
参数:
| 参数名 | 类型 | 必填 | 说明 |
| arr | Array<Object> | 是 | 数据源,为Array类型的数组。 说明: - 可以设置为空数组,此时不会创建子组件。 - 可以设置返回值为数组类型的函数,例如arr.slice(1, 3),但设置的函数不应改变包括数组本身在内的任何状态变量,例如不应使用Array.splice(),Array.sort()或Array.reverse()这些会改变原数组的函数。 |
| itemGenerator | (item: Object, index: number) => void | 是 | 组件生成函数。 - 为数组中的每个元素创建对应的组件。 - item参数:arr数组中的数据项。 - index参数(可选):arr数组中的数据项索引。 说明: - 组件的类型必须是ForEach的父容器所允许的。例如,ListItem组件要求ForEach的父容器组件必须为List组件。 |
| keyGenerator | (item: Object, index: number) => string | 否 | 键值生成函数。 - 为数据源arr的每个数组项生成唯一且持久的键值。函数返回值为开发者自定义的键值生成规则。 - item参数:arr数组中的数据项。 - index参数(可选):arr数组中的数据项索引。 说明: - 如果函数缺省,框架默认的键值生成函数为(item: T, index: number) => { return index + '__' + JSON.stringify(item); } - 键值生成函数不应改变任何组件状态。 |
键值的生成规则和itemGenerator 、keyGenerator有关:
1.如果是keyGenerator这个函数缺省,此时生成规则由框架确定,生成规则为item和index拼接,(item: any, index: number)=>{ return index +“_”+ JSON.stringify(item); }。
2.如果keyGenerator没有缺省且未包含index,当itemGenerator中包含index,生成的规则是自定义键值与index拼接成的字符串,如(item)=>item+2 对应的键值是 index+'_'+(item+2),如果itemGenerator中未包含index,此时keyGenerator的生成规则是由开发者自定义的键值生成规则。
3.如果keyGenerator没有缺省,且包含index,此时不管itemGenerator中是否包含index,生成的键值规则都是开发者自定义的键值生成规格,框架不会对去拼接index。
2. 场景和示例
ForEach在初始化时,会加载数组中所有的数据,并为其创建控件,也就是厨师数组如果有n项,就会创建n个对象
@Component
export struct ForEachView {@State private list: number[] = [1, 2, 3]private list1: number[] = [1, 2]private list2: number[] = [1, 2, 3, 4, 5]private isOne: boolean = true;build() {Column({ space: 20 }) {Column({ space: 10 }) {ForEach(this.list, (item: number) => {Child({ item: item })}, (item: number, index: number) => {console.debug(`ForEach: item = ${item}, index = ${index}`)return item.toString()})}Row({ space: 10 }) {Button("add").onClick(() => {this.list.push(4)})Button("insert").onClick(() => {this.list.splice(1, 0, 5)})Button("delete").onClick(() => {this.list.pop();})Button("changeArray").onClick(() => {if (this.isOne) {this.list = this.list1} else {this.list = this.list2}this.isOne = !this.isOne;})}}}
}@Component
struct Child {@Prop item: number;aboutToAppear(): void {console.debug(`aboutToAppear: child${this.item}`)}build() {Text(this.item.toString()).width(100).height(50).border({ width: 2, color: Color.Red })}aboutToDisappear(): void {console.debug(`aboutToDisappear: child${this.item}`)}}
2.1. 场景一:初始化

运行结果:

初始化时,list中有三个元素,ForEach遍历所有元素,并创建了三个Child控件
2.2. 场景二:数组增加元素

运行结果:

可以看出,增加了Item 4后,ForEach循环还是遍历的四遍,但是此时只有child4执行了aboutToAppear的方法。这是因为ForEach的keyGenerator设置唯一的key值,ForEach刷新时,发现如果相同的key值的控件如果已经存在,就不会重新创建。
2.3. 场景三:数组插入元素

运行结果:

插入和增加一样,ForEach也会全部遍历,但是只创建了不存在的child5
2.4. 场景四:删除

运行结果:

ForEach遍历剩余的元素,并将删除的元素下树,调用child3的aboutToDisapper的方法
2.5. 场景五:更换数组对象
- 将数组list1赋值list, 元素数量减少

运行结果:

由于list1和list之间有部分项的重合,所以,list1赋值给list后,重复的部分之前已经存在,不创建,list1没有的部分则进行了删除
- 将list2赋值给list,元素数量增加

运行结果:

ForEach对所有元素遍历,对不存在的元素进行创建
- 赋值完全不同的list3

运行结果:

ForEach遍历数组所有元素,将原来的元素全部移除,然后创建新的元素。
3. 总结
对于ForEach而言,只要数组发生了变化, 无论是长度变化还是重新赋值, ForEach都回重新遍历一遍。但是ForEach会根据keyGenerator的值判断是否需要重新创建控件,所以keyGenerator是非常关键的参数,建议自己定义一个生成规则,不要用系统默认的。
相关文章:
ForEach刷新UI机制
官网地址:ForEach 在ArkUI中,提供了ForEach循环语句,用来初始化一个列表数据,我们知道,当ForEach中的数组发生变化时,会引起UI的刷新,但是究竟如何变化,会引起UI怎样的刷新…...
机器学习(贝叶斯算法,决策树)
朴素贝叶斯分类 贝叶斯分类理论 假设现有两个数据集,分为两类 我们现在用p1(x,y)表示数据点(x,y)属于类别1(图中红色圆点表示的类别)的概率,用p2(x,y)表示数据点(x,y)属于类别2(图中蓝色三角形表示的类别)的概率,那么对于一个新数据点(x,y)…...
实验十三 生态安全评价
1 背景及目的 生态安全是生态系统完整性和健康性的整体反映,完整健康的生态系统具有调节气候净化污染、涵养水源、保持水土、防风固沙、减轻灾害、保护生物多样性等功能。维护生态安全对于人类生产、生活、健康及可持续发展至关重要。随着城市化进程的不断推进&…...
二级等保要求及设备有哪些?
《网络安全法》规定我国信息系统实际等级保护制度,不同等保等级要求不同: 二级等保(指导保护级):等级保护对象受到破坏后,会对公民、法人和其他组织的合法权益产生严重损害,或者对社会秩序和公…...
无人机的动力系统节能——CKESC电调小课堂12
1.优化电机和螺旋桨配置 精准匹配:根据无人机的设计用途和负载要求,精确选择电机和螺旋桨。确保电机的功率、扭矩等参数与螺旋桨的尺寸、螺距等完美匹配。例如,对于轻型航拍无人机,选用功率合适的小尺寸电机搭配高效的小螺旋桨&a…...
人机打怪小游戏(非常人机)
按q攻击 按箭头进行控制 玩家是 怪是* 攻击是^ #include<bits/stdc.h> #include<Windows.h> #include<conio.h> #define fr(i,a,b) for(int ia;i<b;i) #define rd(a,b) rand()%(b-a1)a using namespace std; int x16,y21,dx[4]{-1,0,1,0},dy[4]{0,…...
SpringBoot 集成 Sharding-JDBC(一):数据分片
在深入探讨 Sharding-JDBC 之前,建议读者先了解数据库分库分表的基本概念和应用场景。如果您还没有阅读过相关的内容,可以先阅读我们之前的文章: 关系型数据库海量数据存储策略-CSDN博客 这篇文章将帮助您更好地理解分库分表的基本原理和实现…...
django-ninja 实现cors跨域请求
要在Django-Ninja项目中实现跨域(CORS),你可以使用django-cors-headers库,这是一个专门用于处理跨域资源共享(CORS)问题的Django应用程序。以下是具体的步骤和配置: 安装依赖: 使用p…...
【论文阅读】InstructPix2Pix: Learning to Follow Image Editing Instructions
摘要: 提出了一种方法,用于教导生成模型根据人类编写的指令进行图像编辑:给定一张输入图像和一条书面指令,模型按照指令对图像进行编辑。 由于为此任务获取大规模训练数据非常困难,我们提出了一种生成配对数据集的方…...
常用在汽车PKE无钥匙进入系统的高度集成SOC芯片:CSM2433
CSM2433是一款集成2.4GHz频段发射器、125KHz接收器和8位RISC(精简指令集)MCU的SOC芯片,用在汽车PKE无钥匙进入系统里。 什么是汽车PKE无钥匙进入系统? 无钥匙进入系统具有无钥匙进入并且启动的功能,英文名称是PKE&…...
【第四课】rust声明式宏理解与实战
目录 前言 理解宏 实战宏 前言 上一课在介绍vector时,我们再一次提到了rust中的宏,在初始化vector时使用了vec!宏,当时补了一句有机会会好好说明一下rust中的宏,并且写一个hashmap宏来初始化hashmap。想了想一直介绍基本语法还…...
渗透测试--Linux下的文件传输方法
渗透测试过程中,我们经常会需要文件传输,本文主要探讨Linux主机上我们对文件传输的方法。 编码方式 Linux 检查MD5 md5sum id_rsa Linux Base64 编码/解码 编码 cat id_rsa |base64 -w 0;echo 解码 echo -n LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVE…...
浅议Flink中的通讯工具: Akka
在Flink中,各个组件之间需要频繁交换数据和控制信息。Flink选择了基于Actor模型的Akka框架作为通信基础。 Akka是什么 Actor模型 Actor模型是用于单个进程中并发的场景。 在Actor模型中: ActorSystem负责管理actor生命周期 将每个实体视为独立的 Ac…...
基于YOLOv8深度学习的独居老人情感状态监护系统(PyQt5界面+数据集+训练代码)
本研究提出了一种创新的独居老人情感状态监护系统,基于YOLOV8深度学习模型,旨在通过对老年人面部表情的实时监测与分析,来精准识别其情感变化,从而提高独居老人的生活质量,确保其心理健康。本系统通过整合先进的YOLOV8…...
Qt添加外部库:静态库和动态库,批量添加头文件
Qt添加外部库需要知道库文件的位置才能正确链接,如果是静态库,要确保LIBS变量中包含正确的库文件路径和库文件名;如果是动态库,除了库路径外,还需要考虑动态库的加载路径。在 Windows 下,可以将动态库所在路径添加到系…...
Unity类银河战士恶魔城学习总结(P132 Merge skill tree with skill Manager 把技能树和冲刺技能相组合)
【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了解锁技能后才可以使用技能,先完成了冲刺技能的锁定解锁 Dash_Skill.cs using System.Collections; using System…...
Docker入门之Windows安装Docker初体验
在之前我们认识了docker的容器,了解了docker的相关概念:镜像,容器,仓库:面试官让你介绍一下docker,别再说不知道了 之后又带大家动手体验了一下docker从零开始玩转 Docker:一站式入门指南&#…...
DNS实验作业
实验要求 1.搭建dns服务器能够对自定义的正向或者反向域完成数据解析查询。 2.配置从DNS服务器,对主dns服务器进行数据备份。 实验步骤: 1.关闭防护墙 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2.正向解析 [rootlo…...
CSS回顾-CSS选择器详解
一、引言 我来填坑啦!之前在CSS基础知识详解中介绍过,CSS 是一门基于规则的语言。是由选择器与样式信息组成:选择器 {样式信息}。CSS 选择器是 CSS 规则的关键,能精准定位 HTML 元素,CSS3 新增选择器更是增强了设计能…...
FFMPEG录像推流时遇到的问题
FFMPEG录像推流时遇到的问题,记录一下供大参考 1. ret avformat_write_header( ofmt_ctx, NULL ); 执行写入头后,所有的流的时间基都会被内部重新设置,所以并不你想象的把原来的时间直接入到avPACKET中就可以发送了。必须要把你每个流的P…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
