鸿蒙开发-ArkTS 语言-循环渲染

鸿蒙开发-ArkTS 语言-状态管理

4. 渲染控制

对于 UI 渲染,可以基于数据结构选择一些内置方法(例如:ForEach)快速渲染 UI 结构。

4.1 if-else条件渲染

ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态,使用if、else和else if渲染对应状态下的UI内容。

条件渲染语句允许基于条件在组件内构建不同子组件,支持if、else、else if语句,条件可以使用状态变量,但需遵循父子组件关系规则,确保每个分支内创建至少一个组件,且子组件类型和数量需符合父组件限制。

代码示例:

@Entry
@Component
struct ViewA {@State count: number = 0;build() {Column() {Text(`count=${this.count}`)if (this.count >= 0) {Text(`count 为正数`).fontColor(Color.Green)} else {Text(`count 为负数`).fontColor(Color.Red)}Button('增 count').onClick(() => {this.count++;})Button('减 count').onClick(() => {this.count--;})}}
}

图示:

gif11

4.2 ForEach:循环渲染

必须使用数组(允许空数组),设置的循环函数不允许改变源数组。

一共三个参数:

  1. ForEach组件接受arr属性作为数组输入,必须是数组类型,允许为空数组,可用返回数组的函数。数组为空时,不会创建子组件。

  2. itemGenerator是必需的,是一个lambda函数,根据数组中的每个数据项生成一个或多个子组件。

  3. 可选的keyGenerator是一个匿名函数,用于生成数组中每个数据项的唯一 key 值。

简单的示例:

@Entry
@Component
struct MyComponent {@State arr: number[] = [10, 20, 30];build() {Column({ space: 5 }) {Button('翻转数组').onClick(() => {this.arr.reverse();})ForEach(this.arr, (item: number) => {Text(`此项值: ${item}`).fontSize(18)Divider().strokeWidth(2)}, (item: number) => item.toString())}}
}

效果如下:

gif12

配合 @ObjectLInk 的 ForEach 示例

let NextID: number = 0;@Observed
class MyCounter {public id: number;public c: number;constructor(c: number) {this.id = NextID++;this.c = c;}
}@Component
struct CounterView {@ObjectLink counter: MyCounter;label: string = '计数器视图';build() {Button(`计数器视图 [${this.label}] this.counter.c=${this.counter.c} +1`).width(400).height(50).onClick(() => {this.counter.c += 1;})}
}@Entry
@Component
struct MainView {@State firstIndex: number = 0;@State counters: Array<MyCounter> = [new MyCounter(0), new MyCounter(0), new MyCounter(0),new MyCounter(0), new MyCounter(0)];build() {Column() {ForEach(this.counters.slice(this.firstIndex, this.firstIndex + 3),(item) => {CounterView({ label: `计数器项目 #${item.id}`, counter: item })},(item) => item.id.toString())Button(`计数器:向上移动`).width(200).height(50).onClick(() => {this.firstIndex = Math.min(this.firstIndex + 1, this.counters.length - 3);})Button(`计数器:向下移动`).width(200).height(50).onClick(() => {this.firstIndex = Math.max(0, this.firstIndex - 1);})}}
}

图示:

gif13

4.3 LazyForEach:数据懒加载

LazyForEach是一个用于按需迭代数据并创建组件的接口,适用于滚动容器以提高性能。它接受数据源、子组件生成函数和可选的键值生成函数作为参数。在每次迭代中,子组件生成函数生成一个子组件,并且键值生成函数可选地用于为数据项生成唯一的键值。

同时,数据变化监听器(DataChangeListener)提供了各种通知方法,如重新加载数据、数据添加、数据移动、数据删除和数据变化。在使用LazyForEach时,需要注意它必须在支持懒加载的容器组件内使用,且生成的子组件必须符合容器组件的规定。

IDataSource类型说明

interface IDataSource {totalCount(): number; // 获得数据总数getData(index: number): any; // 获取索引值对应的数据registerDataChangeListener(listener: DataChangeListener): void; // 注册数据改变的监听器unregisterDataChangeListener(listener: DataChangeListener): void; // 注销数据改变的监听器
}

DataChangeListener类型说明

interface DataChangeListener {onDataReloaded(): void; // 重新加载数据时调用onDataAdded(index: number): void; // 添加数据时调用onDataMoved(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换时调用onDataDeleted(index: number): void; // 删除数据时调用onDataChanged(index: number): void; // 改变数据时调用onDataAdd(index: number): void; // 添加数据时调用onDataMove(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换时调用onDataDelete(index: number): void; // 删除数据时调用onDataChange(index: number): void; // 改变数据时调用
}

懒加载示例:

// 实现基本的IDataSource以处理数据监听器
class BasicDataSource implements IDataSource {private listeners: DataChangeListener[] = [];// 获取数据总数public totalCount(): number {return 0;}// 获取特定索引的数据public getData(index: number): any {return undefined;}// 注册数据变化监听器registerDataChangeListener(listener: DataChangeListener): void {if (this.listeners.indexOf(listener) < 0) {console.info('添加监听器');this.listeners.push(listener);}}// 注销数据变化监听器unregisterDataChangeListener(listener: DataChangeListener): void {const pos = this.listeners.indexOf(listener);if (pos >= 0) {console.info('移除监听器');this.listeners.splice(pos, 1);}}// 通知数据重新加载notifyDataReload(): void {this.listeners.forEach(listener => {listener.onDataReloaded();});}// 通知数据添加notifyDataAdd(index: number): void {this.listeners.forEach(listener => {listener.onDataAdd(index);});}// 通知数据变化notifyDataChange(index: number): void {this.listeners.forEach(listener => {listener.onDataChange(index);});}// 通知数据删除notifyDataDelete(index: number): void {this.listeners.forEach(listener => {listener.onDataDelete(index);});}// 通知数据移动notifyDataMove(from: number, to: number): void {this.listeners.forEach(listener => {listener.onDataMove(from, to);});}
}class MyDataSource extends BasicDataSource {private dataArray: string[] = [];// 获取数据总数public totalCount(): number {return this.dataArray.length;}// 获取特定索引的数据public getData(index: number): any {return this.dataArray[index];}// 添加数据public addData(index: number, data: string): void {this.dataArray.splice(index, 0, data);this.notifyDataAdd(index);}// 推送数据public pushData(data: string): void {this.dataArray.push(data);this.notifyDataAdd(this.dataArray.length - 1);}
}@Entry
@Component
struct MyComponent {aboutToAppear() {for (var i = 100; i >= 80; i--) {this.data.pushData(`Hello ${i}`);}}private data: MyDataSource = new MyDataSource();build() {List({ space: 3 }) {// 使用LazyForEach按需迭代数据LazyForEach(this.data, (item: string) => {ListItem() {Row() {Text(item).fontSize(50).onAppear(() => {console.info("出现:" + item);});}.margin({ left: 10, right: 10 });}.onClick(() => {this.data.pushData(`Hello ${this.data.totalCount()}`);});}, item => item);}.cachedCount(5); // 设置缓存的数据数量}
}

图示:

gif14

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

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

相关文章

案例024:基于微信小程序的汽车保养系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

Robust taboo search for the quadratic assignment problem-二次分配问题的鲁棒禁忌搜索

文章目录 摘要关键字结论研究背景1. Introduction 常用基础理论知识2. The quadratic assignment problem3. Taboo search3.1. Moves3.2 Taboo list3.3. Aspiration function3.4. Taboo list size4. Random problems5. Parallel taboo search 研究内容、成果7. Conclusion 潜在…

webshell之Laravel和yii

EvalLoader#load 免杀效果 EvalLoader#load分析 eval命令执行函数&#xff0c;参数可控 MockTrait#generate 免杀效果 MockTrait#generate函数分析 存在一个eval函数 MockTrait#generate 免杀效果 view#evaluateDynamicContent 免杀效果 view#evaluateDynamicContent分析 总结…

Python中的数据类型

如果说python中的数据类型,那我们要从标准数据类型说起,在python中标准数据类型如下: 数字类型: 数字数据类型用于存储数值。 他们是不可改变的数据类型&#xff0c;这意味着改变数字数据类型会分配一个新的对象。 在python2.X中数据类型分的比较多,有int(有符号整型),long(…

【spring(五)】SpringMvc总结 SSM整合流程

目录 一、SpringMVC简介&#xff1a; 二、SpringMVC快速入门&#xff1a; 三、SpringMVC bean的管理&#xff1a;⭐ ①配置bean ②扫描bean 四、SpringMVC配置类&#xff1a;⭐ 五、SpringMVC 请求与响应 六、SpringMVC REST风格 七、SSM整合 异常处理&#xff1a; 八、…

Unity使用DOTween实现分段进度条

文章目录 需求下载安装 DOTween实现实现效果 需求 用组件进度条&#xff08;Slider&#xff09;&#xff0c;利用分段加载进行以假乱真的进度效果&#xff0c;比如说2秒钟到达20%的进度&#xff0c;10秒钟加载20%到50%进度&#xff0c;1分钟加载50%到90%的进度&#xff0c;30秒…

Python 自动化用处太大了!|python自动整理文件,一键完成!

随着时代的发展及人工智能的到来&#xff0c;Python 自动化办公能力几乎已成为每个岗位的必备技能&#xff01; 而且到处可见的抖音、朋友圈铺天盖地宣传 Python 可以轻松达到办公自动化&#xff0c;并且学习没门槛&#xff0c;是真的吗&#xff1f; 我很负责的告诉大家&#…

【微服务专题】SpringBoot自动配置源码解析

目录 前言阅读对象阅读导航前置知识什么是自动配置0.1 基本概念0.2 SpringBoot中的【约定大于配置】0.3 从SpringMVC看【约定大于配置】0.4 从Redis看【约定大于配置】0.5 小结 笔记正文一、EnableAutoConfiguration源码解析二、SpringBoot常用条件注解源码解析2.1 自定义条件注…

物流公司打印用什么软件,佳易王物流运单打印管理系统软件下载

物流公司打印用什么软件&#xff0c;佳易王物流运单打印管理系统软件下载 软件特色&#xff1a; 1、功能实用&#xff0c;操作简单&#xff0c;不会电脑也会操作&#xff0c;软件免安装&#xff0c;已内置数据库。 2、物流开单打印&#xff0c;可以打印两联单或三联单&#x…

【Unity实战】切换场景加载进度和如何在后台异步加载具有庞大世界的游戏场景,实现无缝衔接(附项目源码)

文章目录 最终效果前言一、绘制不同的场景二、切换场景加载进度1. 简单实现2. 优化 三、角色移动和跳跃控制四、添加虚拟摄像机五、触发器动态加载场景六、最终效果参考源码完结 最终效果 前言 观看本文后&#xff0c;我的希望你对unity场景管理有更好的理解&#xff0c;并且能…

力控软件与多台PLC之间ModbusTCP/IP无线通信

Modbus TCP/IP 是对成熟的 Modbus 协议的改编&#xff0c; 因其开放性、简单性和广泛接受性而在工业自动化系统中发挥着举足轻重的作用。它作为连接各种工业设备的通用通信协议&#xff0c;包括可编程逻辑控制器 (PLC)、远程终端单元 (RTU) 和传感器。它提供标准化的 TCP 接口&…

仿 美团 / 饿了么,店铺详情页功能

前言 UI有所不同&#xff0c;但功能差不多&#xff0c;商品添加购物车功能 正在写&#xff0c;写完会提交仓库。 效果图一&#xff1a;左右RecyclerView 联动 效果图二&#xff1a;通过点击 向上偏移至最大值 效果图三&#xff1a;通过点击 或 拖动 展开收缩公告&#xff08;可…