鸿蒙nextLazyForEach 懒加载来了

2024-09-11  本文已影响0人  xq9527

前言导读

各位同学大家,有段时间没有跟大家见面了,因为最近一直在更新鸿蒙的那个实战课程所以就没有去更新文章实在是不好意思, 昨晚引文有网友问到鸿蒙next 里面的数据懒加载 我这边就做一个分享

效果图

image.png image.png

LazyForEach:数据懒加载

LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当在滚动容器中使用了LazyForEach,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用。

使用限制

键值生成规则

在LazyForEach循环渲染过程中,系统会为每个item生成一个唯一且持久的键值,用于标识对应的组件。当这个键值变化时,ArkUI框架将视为该数组元素已被替换或修改,并会基于新的键值创建一个新的组件。

LazyForEach提供了一个名为keyGenerator的参数,这是一个函数,开发者可以通过它自定义键值的生成规则。如果开发者没有定义keyGenerator函数,则ArkUI框架会使用默认的键值生成函数,即(item: Object, index: number) => { return viewId + '-' + index.toString(); }, viewId在编译器转换过程中生成,同一个LazyForEach组件内其viewId是一致的。

组件创建规则

在确定键值生成规则后,LazyForEach的第二个参数itemGenerator函数会根据键值生成规则为数据源的每个数组项创建组件。组件的创建包括两种情况:LazyForEach首次渲染LazyForEach非首次渲染

具体实现 :

网络请求的数据懒加载

class BasicDataSource implements IDataSource {
  private listeners: DataChangeListener[] = [];
  private originDataArray:  Array<Positiondata> = [];

  public totalCount(): number {
    return 0;
  }

  public getData(index: number): Positiondata {
    return this.originDataArray[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): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      console.info('remove listener');
      this.listeners.splice(pos, 1);
    }
  }

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

  // 通知LazyForEach组件需要在index对应索引处添加子组件
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
    })
  }

  // 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index);
    })
  }

  // 通知LazyForEach组件需要在index对应索引处删除该子组件
  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index);
    })
  }

  // 通知LazyForEach组件将from索引和to索引处的子组件进行交换
  notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMove(from, to);
    })
  }
}

class MyDataSource extends BasicDataSource {

  private dataArray: Array<Positiondata> = [];

  public totalCount(): number {
    return this.dataArray.length;
  }

  public getData(index: number): Positiondata {
    return this.dataArray[index];
  }

  public addData(index: number, data:Positiondata): void {
    this.dataArray.splice(index, 0, data);
    this.notifyDataAdd(index);
  }

  public pushData(data: Positiondata): void {
    this.dataArray.push(data);
    this.notifyDataAdd(this.dataArray.length - 1);
  }
}
private JokeListdata: MyDataSource = new MyDataSource();


@State TAG: string = 'Companylist  --- > '
@State positiondata: Positiondata = new Positiondata()
@State JokeList: Array<Positiondata> = []


async  aboutToAppear(){
  Logger.error(this.TAG+' aboutToAppear  --- > ');
  let networkurl=CommonConstant.DISH;
  await httpRequestGet(networkurl).then((data)=>{
    console.log(this.TAG +"data --- > "+data);
    Logger.error(this.TAG+"登录请求回调结果 ---> " +data.toString());
    let positionmodel : PositionModel = JSON.parse(data.toString())
    this.JokeList = positionmodel.data
    for (let i = 0; i <=   this.JokeList.length; i++) {
      this.JokeListdata.pushData(this.JokeList[i]);
    }
  });
}

使用懒加载开发长列表界面

针对List、Grid、WaterFlow、Swiper组件,提供NodeAdapter对象替代ArkTS侧的LazyForEach功能,用于按需生成子组件,其中List组件的属性枚举值为NODE_LIST_NODE_ADAPTER,Grid组件的属性枚举值为NODE_GRID_NODE_ADAPTER,WaterFlow组件的属性枚举值为NODE_WATER_FLOW_NODE_ADAPTER,Swiper组件的属性枚举值为NODE_SWIPER_NODE_ADAPTER。

虽然都用于按需生成组件,但不同于ArkTS的LazyForEach,NodeAdapter对象的规格如下:

最后总结

今天分享的list 组建里面的 LazyForEach 懒加载类似我们安卓里面adapter 和ios里面自定义的cell 就是我们滑动页面的时候加载新的item的时候系统不再重新创建对象 而是回收我们已经使用过item的对象 这样我们就可以复用item 就可以在加载 长 列表的时候减少开销从而提升滑动的性能和流畅度。 因为篇幅有限我也不能整个项目都展开讲,有兴趣的同学能可以关注我B站课程。 后续能我会把这个项目更新到项目里面 供大家学习

B站课程地址:www.bilibili.com/cheese/play…

上一篇 下一篇

猜你喜欢

热点阅读