ppt做书模板下载网站进一步优化
ArkUI开发框架是一套构建 HarmonyOS / OpenHarmony 应用界面的声明式UI开发框架,它支持程序使用 if/else
条件渲染, ForEach
循环渲染以及 LazyForEach
懒加载渲染。本节笔者介绍一下这三种渲染方式的使用。
if/else条件渲染
使用 if/else
进行条件渲染需要注意以下情况:
-
if 条件语句可以使用状态变量。
-
使用 if 可以使子组件的渲染依赖条件语句。
-
必须在容器组件内使用。
-
某些容器组件限制子组件的类型或数量。将if放置在这些组件内时,这些限制将应用于 if 和 else 语句内创建的组件。例如,
Grid
组件的子组件仅支持GridItem
组件,在Grid
组件内使用条件渲染时,则 if 条件语句内仅允许使用GridItem
组件。简单样例如下所示:
@Entry @Component struct ComponentTest {@State showImage: boolean = false;build() {Column({space: 10}) {if (this.showImage) { // 显示图片Image($r("app.media.test")).width(160).height(60).backgroundColor(Color.Pink)} else { // 显示文本Text('Loading...').fontSize(23).width(160).height(60).backgroundColor(Color.Pink)}Button(this.showImage ? 'Image Loaded' : 'Load Image') // 按钮文字.size({width: 160, height: 40}).backgroundColor(this.showImage ? Color.Gray : '#aabbcc')// 按钮背景色.onClick(() => {this.showImage = true; // 设置标记位})}.width('100%').height('100%').padding(10)} }
样例运行结果如下图所示:
ForEach循环渲染
ArkUI开发框架提供循环渲染(ForEach组件)来迭代数组,并为每个数组项创建相应的组件。
ForEach
定义如下:
interface ForEach {(arr: Array<any>, itemGenerator: (item: any, index?: number) => void,keyGenerator?: (item: any, index?: number) => string): ForEach;
}
-
arr:必须是数组,允许空数组,空数组场景下不会创建子组件。
-
itemGenerator:子组件生成函数,为给定数组项生成一个或多个子组件。
-
keyGenerator:匿名参数,用于给定数组项生成唯一且稳定的键值。
简单样例如下所示:
@Entry @Component struct ComponentTest {private textArray: string[] = ["1", "2", "3", "4", "5"]; // 数据源build() {Column({space: 10}) {ForEach(this.textArray, (item: string, index?: number) => { // 循环数组创建每一个ItemText(`Text: ${item}`) // 可以生成一个或多个子组件.fontSize(20).backgroundColor(Color.Pink).margin({ top: 10 })})}.width('100%').height('100%').padding(10)} }
样例运行结果如下图所示:
鸿蒙OS开发 | 更多内容↓点击 《鸿蒙NEXT星河版开发学习文档》 | HarmonyOS与OpenHarmony技术 |
---|
LazyForEach循环渲染
ArkUI开发框架提供数据懒加载( LazyForEach
组件)从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。
-
LazyForEach
定义如下:// LazyForEach定义 interface LazyForEach {(dataSource: IDataSource, itemGenerator: (item: any, index?: number) => void,keyGenerator?: (item: any, index?: number) => string): LazyForEach; }// IDataSource定义 export declare interface IDataSource {totalCount(): number;getData(index: number): any;registerDataChangeListener(listener: DataChangeListener): void;unregisterDataChangeListener(listener: DataChangeListener): void; }// DataChangeListener定义 export declare interface DataChangeListener {onDataReloaded(): void;onDataAdded(index: number): void;onDataMoved(from: number, to: number): void;onDataDeleted(index:number): void;onDataChanged(index:number): void; }
- itemGenerator:子组件生成函数,为给定数组项生成一个或多个子组件。
- keyGenerator:匿名参数,用于给定数组项生成唯一且稳定的键值。
- dataSource:实现
IDataSource
接口的对象,需要开发者实现相关接口。
-
IDataSource
定义如下:export declare interface IDataSource {totalCount(): number;getData(index: number): any;registerDataChangeListener(listener: DataChangeListener): void;unregisterDataChangeListener(listener: DataChangeListener): void; }
- totalCount:获取数据总数。
- getData:获取索引对应的数据。
- registerDataChangeListener:注册改变数据的监听器。
- unregisterDataChangeListener:注销改变数据的监听器。
-
DataChangeListener
定义如下:export declare interface DataChangeListener {onDataReloaded(): void;onDataAdded(index: number): void;onDataMoved(from: number, to: number): void;onDataDeleted(index:number): void;onDataChanged(index:number): void; }
- onDataReloaded:item重新加载数据时的回调。
- onDataAdded:item新添加数据时的回调。
- onDataMoved:item数据移动时的回调。
- onDataDeleted:item数据删除时的回调。
- onDataChanged:item数据变化时的回调。
简单样例如下:
// 定义Student
class Student {public sid: number;public name: string;public age: numberpublic address: stringpublic avatar: stringconstructor(sid: number = -1, name: string, age: number = 16, address: string = '北京', avatar: string = "") {this.sid = sid;this.name = name;this.age = age;this.address = address;this.avatar = avatar;}
}// 定义DataSource
abstract class BaseDataSource<T> implements IDataSource {private mDataSource: T[] = new Array();constructor(dataList: T[]) {this.mDataSource = dataList;}totalCount(): number {return this.mDataSource == null ? 0 : this.mDataSource.length}getData(index: number): T|null {return index >= 0 && index < this.totalCount() ? this.mDataSource[index] : null;}registerDataChangeListener(listener: DataChangeListener) {}unregisterDataChangeListener(listener: DataChangeListener) {}}//
class StudentDataSource extends BaseDataSource<Student> {constructor(students: Student[]) {super(students)}
}function mock(): Student[] {var students = [];for(var i = 0; i < 20; i++) {students[i] = new Student(i, "student:" + i, i + 10, "address:" + i, "app.media.test")}return students;
}@Entry @Component struct ComponentTest {// mock数据private student: Student[] = mock();// 创建dataSourceprivate dataSource: StudentDataSource = new StudentDataSource(this.student);build() {Column({space: 10}) {List() {LazyForEach(this.dataSource, (item: Student) => {// LazyForEach使用自定义dataSourceListItem() {Row() {Image($r("app.media.test")).height('100%').width(80)Column() {Text(this.getName(item)) // 调用getName验证懒加载.fontSize(20)Text('address: ' + item.address).fontSize(17)}.margin({left: 5}).alignItems(HorizontalAlign.Start).layoutWeight(1)}.width('100%').height('100%')}.width('100%').height(60)})}.divider({strokeWidth: 3,color: Color.Gray}).width('90%').height(160).backgroundColor(Color.Pink)}.width('100%').height('100%').padding(10)}getName(item: Student): string {console.log("index: " + item.sid); // 打印item下标日志return 'index:' + item.sid + ", " + item.name;}
}
样例运行结果如下图所示:
打印结果如下:
[phone][Console INFO] 04/02 23:54:19 82919424 app Log: Application onCreate
[phone][Console DEBUG] 04/02 23:54:19 82919424 app Log: index: 0
[phone][Console DEBUG] 04/02 23:54:19 82919424 app Log: index: 1
[phone][Console DEBUG] 04/02 23:54:19 82919424 app Log: index: 2
[phone][Console DEBUG] 04/02 23:54:19 82919424 app Log: index: 3
[phone][Console DEBUG] 04/02 23:54:19 82919424 app Log: index: 4
[phone][Console DEBUG] 04/02 23:54:19 82919424 app Log: index: 5
使用懒加载,可以有效的降低资源占用