0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

鸿蒙ArkUI开发学习:【渲染控制语法】

jf_46214456 来源:jf_46214456 作者:jf_46214456 2024-04-09 16:40 次阅读

ArkUI开发框架是一套构建 HarmonyOS / OpenHarmony 应用界面的声明式UI开发框架,它支持程序使用 if/else 条件渲染, ForEach 循环渲染以及 LazyForEach 懒加载渲染。本节笔者介绍一下这三种渲染方式的使用。

if/else条件渲染

使用 if/else 进行条件渲染需要注意以下情况:

  • if 条件语句可以使用状态变量。

  • 使用 if 可以使子组件的渲染依赖条件语句。

  • 必须在容器组件内使用。

  • 某些容器组件限制子组件的类型或数量。将if放置在这些组件内时,这些限制将应用于 ifelse 语句内创建的组件。例如,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)
      }
    }
    

    样例运行结果如下图所示:

    2_4_1

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) = > { // 循环数组创建每一个Item
        Text(`Text: ${item}`)                                     // 可以生成一个或多个子组件
          .fontSize(20)
          .backgroundColor(Color.Pink)
          .margin({ top: 10 })
      })
    }
    .width('100%')
    .height('100%')
    .padding(10)
  }
}

样例运行结果如下图所示:

2_4_2

LazyForEach循环渲染

搜狗高速浏览器截图20240326151547.png

ArkUI开发框架提供数据懒加载( LazyForEach 组件)从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。

  1. 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 接口的对象,需要开发者实现相关接口。
  2. IDataSource 定义如下:

    export declare interface IDataSource {
      totalCount(): number;
      getData(index: number): any;
      registerDataChangeListener(listener: DataChangeListener): void;
      unregisterDataChangeListener(listener: DataChangeListener): void;
    }
    
    • totalCount :获取数据总数。
    • getData :获取索引对应的数据。
    • registerDataChangeListener :注册改变数据的监听器。
    • unregisterDataChangeListener :注销改变数据的监听器。
  3. 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: number
  public address: string
  public avatar: string
  constructor(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();

  // 创建dataSource
  private dataSource: StudentDataSource = new StudentDataSource(this.student);

  build() {
    Column({space: 10}) {
      List() {
        LazyForEach(this.dataSource, (item: Student) = > {// LazyForEach使用自定义dataSource
          ListItem() {
            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;
  }
}

样例运行结果如下图所示:

2_4_3

打印结果如下:

[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

使用懒加载,可以有效的降低资源占用

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 鸿蒙
    +关注

    关注

    55

    文章

    1644

    浏览量

    42123
  • HarmonyOS
    +关注

    关注

    79

    文章

    1859

    浏览量

    29267
  • OpenHarmony
    +关注

    关注

    23

    文章

    3321

    浏览量

    15161
收藏 人收藏

    评论

    相关推荐

    鸿蒙ArkUI开发-Video组件的使用

    以视频功能为例,在应用开发过程中,我们需要通过ArkUI提供的Video组件为应用增加基础的视频播放功能。借助Video组件,我们可以实现视频的播放功能并控制其播放状态。常见的视频播放场景包括观看网络上的较为流行的短视频,也包括
    的头像 发表于 01-23 16:59 622次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>ArkUI</b><b class='flag-5'>开发</b>-Video组件的使用

    免费学习鸿蒙(HarmonyOS)开发,一些地址分享

    国内一流高校。通过鸿蒙班的设立,高校可以为学生提供专业的鸿蒙OS学习环境和丰富的实践机会,培养出更多的鸿蒙开发人才,为
    发表于 01-12 20:48

    鸿蒙开发OpenHarmony组件复用案例

    ,下面分享一张鸿蒙4.0的学习路线图 :(略缩版) 高清完整版可以在主页保存↓↓↓ (附文档鸿蒙4.0) 注意事项 @Reusable之前的装饰器的名称为@Recycle,旧名称不使用了。 ForEach
    发表于 01-15 17:37

    请问鸿蒙系统是否支持native侧opengles渲染引擎开发

    鸿蒙系统是否支持native侧opengles渲染引擎开发
    发表于 05-27 15:11

    HDD杭州站•ArkUI开发更灵活

    。 采用声明式语法,更符合开发者绘制习惯。 框架集成Canvas能力,无需引入Web引擎。 同时,ArkUI还提供离屏绘制能力。当绘制的图形比较复杂时,频繁的删除与重绘会消耗很多性能。这时,
    发表于 08-05 11:33

    ArkUI框架,更懂程序员的UI信息语法

    原文:​​https://mp.weixin.qq.com/s/LQA6AYiG8O_AeGE1PZwxZg​​,点击链接查看更多技术内容。 ArkUI框架简化代码的“秘密” 在传统的开发
    发表于 12-14 11:23

    ArkUI,更高效的框架设计

    ArkUI是一套用于构建HarmonyOS应用界面的UI开发框架,本期我们将从架构设计上来聊聊ArkUI的设计理念。 ArkUI架构图 从架构图可以看出,
    发表于 12-21 10:26

    4天带你上手HarmonyOS ArkUI开发——《HarmonyOS ArkUI入门训练营之健康生活实战》

    者快速提升技能实力进阶。目标学员入门开发者(计算机专业相关)学习链接:https://t.elecfans.com/c2241.html训练营目标通过学习ArkUI入门训练营课程,了解
    发表于 01-05 11:49

    ArkUI新能力,助力应用开发更便捷

    ArkUI是一套构建分布式应用的声明式UI开发框架。它具备简洁自然的UI信息语法、丰富的UI组件、多维的状态管理,以及实时界面预览等相关能力,帮助您提升应用开发效率,并能在多种设备上实
    发表于 02-15 11:40

    OpenHarmony应用开发-ArkUI方舟开发框架简析

    方舟开发框架(简称ArkUI)为OpenHarmony应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可
    发表于 04-23 09:35

    HarmonyOS/OpenHarmony应用开发-ArkTS语言渲染控制概述

    ArkUI通过自定义组件的build()函数和@builder装饰器中的声明式UI描述语句构建相应的UI。 在声明式描述语句中开发者除了使用系统组件外,还可以使用渲染控制语句来辅助U
    发表于 08-09 09:54

    HarmonyOS/OpenHarmony应用开发-ArkTS语言渲染控制if/else条件渲染

    ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态,使用if、else和else if渲染对应状态下的UI内容。说明:从API version 9开始,该接口支持在ArkTS
    发表于 08-21 14:29

    ArkUI新能力,助力应用开发更便捷

    作者:niulihua,华为ArkUI技术专家;wanglei,华为ArkUI技术专家 ArkUI是一套构建分布式应用的声明式UI开发框架。它具备简洁自然的UI信息
    的头像 发表于 02-15 16:35 672次阅读

    鸿蒙ArkUI开发-Tabs组件的使用

    鸿蒙ArkUI开发-Tabs组件的使用
    的头像 发表于 01-19 16:01 442次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>ArkUI</b><b class='flag-5'>开发</b>-Tabs组件的使用

    鸿蒙ArkUI开发实战:eTS版【笑话app】

    制作一款笑话app,使用ArkUI
    的头像 发表于 03-25 16:04 194次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>ArkUI</b><b class='flag-5'>开发</b>实战:eTS版【笑话app】