鸿蒙 forEach和LazyForEach

此文章内容兼容API12,使用harmony next应用开发

概念解释

forEach 和 LazyForEach 都是应用于循环渲染,forEach 一般应用于数据量小,性能要求不高的场景;LazyForEach适用于数据量大,对性能要求较高的场景。

比较维度forEachLazyForEach
数据源ArrayIDataSource类型
渲染策略一次性渲染所有的数据只渲染可视区域的数据
内存一次性加载所有的数据只加载可视区域的数据,并且对划出可视区域的内容进行回收
数据监听依赖于数组变化触发的UI更新通过DataChangeListener来监听数据的变化,手动通知数据变动以刷新UI
组件支持无限制只支持滚动容器组件,list、grid、swiper、waterFlow
键值对可选[默认键值对默认的键值生成函数,即(item: any, index: number) => { return index + ‘__’ + JSON.stringify(item) }]可选[默认键值对默认的键值生成函数,即(item: any, index: number) => { return viewId + ‘-’ + index.toString(); }]

使用详解 - forEach

list.forEach((bean:xxxobject, index) => {})

使用详解 - LazyForEach

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; // 改变数据完成后调用
}

使用[很像安卓的Adapter]

class AdvDataSource implements IDataSource {
  private listeners: DataChangeListener[] = [];
  private list: CommonDetailBean[] = []

  constructor(list: CommonDetailBean[]) {
    this.list = list
  }

  totalCount(): number {
    return this.list.length
  }

  getData(index: number): CommonDetailBean{
    return this.list[index]
  }

  // 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      console.info('add listener');
      this.listeners.push(listener);
    }
  }

  // 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
  unregisterDataChangeListener(listener: DataChangeListener) {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      console.info('remove listener');
      this.listeners.splice(pos, 1);
    }
  }

  resetData(list: CommonDetailBean[]) {
    this.list = list;
    this.notifyDataReload();
  }

  // 通知LazyForEach组件需要重载所有子组件
  notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded();
    })
  }
}

@Component
{
  @State private data: AdvDataSource = new AdvDataSource(this.advBeanArray)

LazyForEach(this.data, (item: CommonDetailBean, index: number) => {
        Image(this.getImgUrl(item))
          .width('100%')
          .height('100%')
          .alt($r('app.media.home_banner'))
      }), (item: CommonDetailBean, index: number) => {
            return JSON.stringify(item) + index;
          }
}

问题

1,解决LazyForEach数据源变更后界面闪烁的问题:去除ForEach中的index参数

Repeat

官方推出新的渲染组件,Repeat,提供了两种模式non-virtualScroll模式和virtualScroll模式。
non-virtualScroll模式类似于ForEach的使用。渲染短数据列表、组件全部加载的场景
virtualScroll模式类似于LazyForEach的使用。渲染需要懒加载的长数据列表、通过组件复用优化性能表现的场景。需要创建模板代码,用于复用view。
Repeat:可复用的循环渲染-其他状态管理-状态管理(V2)-状态管理-学习ArkTS语言-基础入门 - 华为HarmonyOS开发者

Repeat

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值