【HarmonyOS Next】鸿蒙循环渲染ForEach,LazyForEach,Repeat使用心得体会

news/2025/2/26 19:49:00

ForEachLazyForEachRepeat_0">【HarmonyOS Next】鸿蒙循环渲染ForEach,LazyForEachRepeat使用心得体会

ForEachLazyForEachRepeat_2">一、ForEach,LazyForEachRepeat三者关系

在鸿蒙中列表组件循环渲染的实现,一般都是通过ForEach来配合列表容器组件实现,例如List。也可以直接ForEach去创建多个相同的View。

以下代码,是个简单的ForEach使用。在list组件中通过包裹ForEach循环渲染创建子组件。数据通过传入数组对象的形式,批量一次性循环渲染更新完数据。

需要注意的是,ForEach组件进行非首次渲染时,它会检查新生成的键值是否在上次渲染中已经存在。如果键值不存在,则会创建一个新的组件;如果键值存在,则不会创建新的组件,而是直接渲染该键值所对应的组件。

作为移动开发转鸿蒙,笔者喜欢将列表容器的子组件称之为,ItemVIew。

渲染最终效果是,自上而下显示三行文本的垂直列表



struct ListPage {
   tempList: Array<string> = ['第一行代码', '开发艺术探索', '入门到精通'];

  build() {
    Row() {
      List() {
        ForEach(this.tempList, (item: string) => {
          ListItem(){
      		ItemView ({ item: item })
      		   .margin({top: 30})
		  }
        }, (item: string) => item)
      }
      .width('100%')
      .height('100%')
    }
    .alignListItem(ListItemAlign.Center)
    .height('100%')

  }
}


struct ItemView {
   item: string;

  build() {
    Text(this.item)
      .fontSize(50)
  }
}

使用起来相当简单,但是实际业务开发中,大批量的列表数据渲染还是用这种方式,在首次加载时会造成性能卡顿。例如我有一万条数据,那就需要创建一万个ItemVIew,渲染压力可见非常恐怖。

为了解决该问题,所以LazyForEach应运而生。这两者主要的区别就是数据不一次性加载渲染,**懒加载通过提供的数据源中按需迭代数据。**通过继承BasicDataSource来监听控制列表的数据源进行按需加载。

框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用。【比起Android和IOS的回收机制,这里设计的并不完美。因为没有复用机制。】

正因为LazyForEach的不足点,所以V2中又提供了Repeat来实现循环回收复用机制,也简化了数据源控制刷新的模板代码。

ForEachLazyForEach_55">二、ForEach,LazyForEach的局限性

ForEach
1.只能一次性渲染列表内所有数据去创建VIew,没办法按需加载,性能损耗严重,内存占用大。
2.索引自己维护,容易造成不可知的UI问题。例如索引一致后,UI刷新会异常。

LazyForEach
1.只能在容器列表组件中使用
2.数据源的样板配置代码太过于冗余
3.回收机制,没有复用View,快速列表时,还是会有性能损耗

Repeat_66">三、Repeat的优点和和使用介绍

Repeat提供了两种模式non-virtualScroll模式和virtualScroll模式。

non-virtualScroll模式类似于ForEach的使用。渲染短数据列表、组件全部加载的场景。



struct ListPage {
   tempList: Array<string> = ['第一行代码', '开发艺术探索', '入门到精通'];

  build() {
    Row() {
      Column() {
        Text('点击修改第1个数组项的值')
          .fontSize(24)
          .fontColor(Color.Red)
          .onClick(() => {
            this.simpleList[0] = 'HarmonyOS第一行代码';
          })

        Repeat<string>(this.tempList)
            .each((res: RepeatItem<string>)=>{
              ItemView({ item: res.item })
                .margin({top: 30})
            })
            .key((item: string) => item)
      }
      .justifyContent(FlexAlign.Center)
      .width('100%')
      .height('100%')
    }
    .height('100%')
    .backgroundColor(0xF1F3F5)
  }
}


struct ItemView {
    data: string;

  build() {
    Text(this.data)
      .fontSize(30)
  }
}

virtualScroll模式类似于LazyForEach的使用。渲染需要懒加载的长数据列表、通过组件复用优化性能表现的场景。需要创建模板代码,用于复用view。 点击跳转参考官方示例代码

Repeat首次渲染时,根据容器组件的有效加载范围(可视区域+预加载区域)创建当前需要的子组件。

在容器滑动/数组改变时,将失效的子组件节点(离开有效加载范围)加入空闲节点缓存列表中(断开与组件树的关系,但不销毁),在需要生成新的组件时,对缓存里的组件进行复用(更新被复用子组件的变量值,重新上树)。

需要注意的是,Repeat要配合V2状态管理装饰器来使用。virtualScroll模式不支持V1装饰器,混用V1装饰器会导致渲染异常,不建议开发者同时使用。


http://www.niftyadmin.cn/n/5869119.html

相关文章

LeetCode 解题思路 2(Hot 100)

解题思路&#xff1a; 哈希去重&#xff1a; 将所有元素存入哈希集合。遍历检查起点&#xff1a; 对每个元素&#xff0c;若其前驱不存在&#xff0c;则作为起点开始向后扩展&#xff0c;统计最长连续序列。 Java代码&#xff1a; class Solution {public int longestConsec…

线代[8]|北大丘维声教授《怎样学习线性代数?》(红色字体为博主本人注释)

文章目录 说明一、线性代数的内容简介二、学习线性代数的用处三、线性代数的特点四、学习线性代数的方法五、更新时间记录 说明 文章中红色字体为博主敲录完丘教授这篇文章后所加&#xff0c;刷到这篇文章的读者在首次阅读应当跳过红色字体&#xff0c;先通读一读文章全文&…

rust笔记10-多线程

在 Rust 中,Sync 和 Send 是用于多线程编程的两个关键 trait,它们帮助确保线程安全和数据同步。 Send 和 Sync Trait Send: 表示类型的所有权可以在线程间安全传递。如果一个类型实现了 Send,它的实例可以从一个线程移动到另一个线程。大多数类型都实现了 Send,但像 Rc<…

SSH.NET: .NET 平台上的安全 Shell 库

简介 SSH.NET 是一个针对 .NET 平台优化的 Secure Shell (SSH-2) 库&#xff0c;支持并行操作。它提供了丰富的功能&#xff0c;包括执行 SSH 命令、SFTP 和 SCP 文件传输、端口转发、交互式终端等功能&#xff0c;并支持多种认证方式和加密方法。 主要特性 命令执行&#x…

【QT】QLinearGradient 线性渐变类简单使用教程

目录 0.简介 1&#xff09;qtDesigner中 2&#xff09;实际执行 1.功能详述 3.举一反三的样式 0.简介 QLinearGradient 是 Qt 框架中的一个类&#xff0c;用于定义线性渐变效果&#xff08;通过样式表设置&#xff09;。它可以用来填充形状、背景或其他图形元素&#xff0…

危化品经营单位安全管理人员的职责及注意事项

危化品经营单位安全管理人员肩负着保障经营活动安全的重要责任&#xff0c;以下是其主要职责及注意事项&#xff1a; 职责 1. 安全制度建设与执行&#xff1a;负责组织制定本单位安全生产规章制度、操作规程和生产安全事故应急救援预案&#xff0c;确保这些制度符合国家相关法…

【原创工具】同文件夹PDF文件合并 By怜渠客

【原创工具】同文件夹PDF文件合并 By怜渠客 原贴&#xff1a;可批量合并多个文件夹内的pdf工具 - 吾爱破解 - 52pojie.cn 他这个存在一些问题&#xff0c;并非是软件内自主实现的PDF合并&#xff0c;而是调用的pdftk这一工具&#xff0c;但楼主并没有提供pdftk&#xff0c;而…

SQL之order by盲注

目录 一.order by盲注的原理 二.注入方式 a.布尔盲注 b.时间盲注 三.防御 一.order by盲注的原理 order by子句是用于按指定列排序查询结果&#xff0c;列名或列序号皆可。 order by 后面接的字段或者数字不一样&#xff0c;那么这个数据表的排序就会不同。 order by 盲…