《跟我一起学“Harmony-ArkTS”》——懒加载(LazyForEach)

一、数据加载方式

在之前的文章里,我已经向大家介绍了一种循环渲染数据的方式(《跟我一起学“Harmony-ArkTS”——页面元素渲染》),就是ForEach,ForEach加载数据的特点就是,如果列表数据较少,数据一次性全量加载不是性能瓶颈,可以使用ForEach一次性加载全量数据
ForEach可如果有上万条数据,一次性加载上万条数据,必然会造成性能问题,同时,我们是否有必要在当前时刻一次性加载上万条数据呢?如何解决这些问题,这个时候,我们就引出了今天的主角:懒加载——LazyForEach了。
LazyForEach实现了按需加载,针对列表数据量大、列表组件复杂的场景,减少了页面首次启动时一次性加载数据的时间消耗,减少了内存峰值
LazyForEach简单的理论介绍完了,如何使用LazyForEach呢,咱们接着往下看。
在使用方面,LazyForEach与ForEach不同点在于,ForEach里所接收的数据源类型可以是任意的,而LazyForEach里所接收的数据源类型,必须是实现了IDataSource接口的类型。
因此,案例代码如下:

/**
 * 实现IDataSource接口
 */
class BasicDataSource implements IDataSource {
  /**
   * 监听器
   */
  private listeners: DataChangeListener[] = [];
  /**
   * 这里应该是来自后端给的数据列表
   * 本文章举例子为了简单实现就用了简单数据
   */
  private originDataArray: Array<string> = [
    '你好鸿蒙',
    '你好鸿蒙',
    '你好鸿蒙',
    '你好鸿蒙',
    '你好鸿蒙',
    '你好鸿蒙',
    '你好鸿蒙',
    '你好鸿蒙',
    '你好鸿蒙',
    '你好鸿蒙',
    '你好鸿蒙',
    '你好鸿蒙',
  ];

  /**
   * 获取总数
   *
   * @returns 总数
   */
  public totalCount(): number {
    return this.originDataArray.length;
  }

  /**
   * 获取指定位置的数据
   * 注意:这里函数的返回类型应该与后端返回数据列表的数据类型一致
   *
   * @param index 索引
   * @returns 指定位置的数据
   */
  public getData(index: number): string {
    return this.originDataArray[index];
  }

  /**
   * 为LazyForEach组件向其数据源处添加listener监听
   *
   * @param listener 监听器
   */
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      console.info('add listener');
      this.listeners.push(listener);
    }
  }

  /**
   * 为对应的LazyForEach组件在数据源处去除监听器
   *
   * @param listener 监听器
   */
  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      console.info('remove listener');
      this.listeners.splice(pos, 1);
    }
  }

  /**
   * 重新加载所有组件
   */
  onDataReloaded(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded();
    })
  }

  /**
   * 在指定位置添加子组件
   *
   * @param index 索引
   */
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
    })
  }

  /**
   * 指定位置重新加载子组件
   *
   * @param index 索引
   */
  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index);
    })
  }

  /**
   * 指定位置删除子组件
   *
   * @param index 索引
   */
  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index);
    })
  }

  /**
   * 将指定位置的组件交换
   *
   * @param from 原索引
   * @param to 目标索引
   */
  notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMove(from, to);
    })
  }
}

@Entry
@Component
struct LazyForEachPage {
  private title: string = '懒加载案例';
  private data: BasicDataSource = new BasicDataSource();

  build() {
    Column({ space: 50 }) {
      Text(this.title)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      List({ space: 20 }) {
        LazyForEach(this.data, (item: string, index: number) => {
          ListItem() {
            Text(index + 1 + ':' + item)
              .fontSize(50)
              .fontWeight(FontWeight.Bold)
              .textAlign(TextAlign.Center)
              .backgroundColor(Color.Pink)
          }
          .width('100%')
        })
      }
      .alignListItem(ListItemAlign.Center)
      .height('30%')
      .width('100%')
      .backgroundColor(Color.Gray)
    }
  }
}

基础代码虽然出来了,但是这里面其实还遗留了一个小问题。目前我们的模拟数据偏少也偏简单,当数据稍微多点稍微偏复杂了以后,用户滑动到列表最底端时,在快速下滑,可能会引起“滑动白块”的现象。这是因为用户上一次只请求了可视区上的3条数据,如果滑动速度过快,后导致数据来不及加载而出现白块,会给用户带来糟糕的体验。那么怎么解决这个问题呢?您且听我娓娓道来。
为了解决“滑动白块”问题,我们可以为懒加载添加缓存列表项。LazyForEach可以通过设置cacheCount来指定缓存数量,在设置缓存cacheCount后,除可视区内显示的ListItem组件外,还会预先将可视区外指定数量的列表项数据缓存。这样当一个可视区数据加载完成后,再次向下滑动,会先加载上一次请求的数据,加载完后,在加载本次请求的数据,进而解决“滑动白块”的问题。
案例代码如下:

@Entry
@Component
struct LazyForEachPage {
  private title: string = '懒加载案例';
  private data: BasicDataSource = new BasicDataSource();

  build() {
    Column({ space: 50 }) {
      Text(this.title)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      List({ space: 20 }) {
        LazyForEach(this.data, (item: string, index: number) => {
          ListItem() {
            Text(index + 1 + ':' + item)
              .fontSize(50)
              .fontWeight(FontWeight.Bold)
              .textAlign(TextAlign.Center)
              .backgroundColor(Color.Pink)
          }
          .width('100%')
        })
      }
      .alignListItem(ListItemAlign.Center)
      .cachedCount(3) // 设置缓冲区配置
      .height('30%')
      .width('100%')
      .backgroundColor(Color.Gray)

      Button('返回')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          router.back();
        })
    }
  }
}

只需在List组件上配置cacheCount属性即可

以上就是懒加载的使用方法,更多关于LazyForEach使用方法的内容,大家可以参考LazyForEach官方文档进行深入学习。

二、小结

本章言简意赅的为大家介绍了懒加载(LazyForEach),下一章,为大家介绍视频组件和二维码组件的内容。最后,创作不易,如果大家觉得我的文章对学习鸿蒙有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学徒钝子生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值