HarmonyOS 鸿蒙Next中懒加载列表问题

HarmonyOS 鸿蒙Next中懒加载列表问题 大家好,我最近学习了懒加载生成列表的课程,但是课程里面都是用的模拟数据,我想知道,在实际开发中,数据一般都是从服务器获取的,那么应该如何结合懒加载、触底加载数据获取增量信息呢?

4 回复

尊敬的开发者,您好, 滚动到List组件底部时,在onReachEnd中,通过addLastItem()实现加载,可以参考如下示例:

关键代码如下:

      .onReachEnd(() => {
        // 滚动到列表底部时触发加载
        if (!this.isLoading) {
          this.isLoading = true;
        }
        for (let i = 0; i < 6; i++) {
          this.arr.addLastItem()
        }
        this.isLoading = false;

      })

完整示例代码如下:

// ListDataSource.ets
export class ListDataSource implements IDataSource {
  private list: number[] = [];
  private listeners: DataChangeListener[] = [];

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

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

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

  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      this.listeners.push(listener);
    }
  }

  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      this.listeners.splice(pos, 1);
    }
  }

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

  // 通知控制器数据删除
  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index);
    });
  }

  // 通知控制器添加数据
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
    });
  }

  // 在指定索引位置删除一个元素
  public deleteItem(index: number): void {
    this.list.splice(index, 1);
    this.notifyDataDelete(index);
  }

  // 在指定索引位置插入一个元素
  public insertItem(index: number, data: number): void {
    this.list.splice(index, 0, data);
    this.notifyDataAdd(index);
  }
  public addLastItem(): void {
    this.list.splice(this.list.length, 0, this.list.length);
    this.notifyDataAdd(this.list.length - 1);
  }

  public reloadData(): void {
    this.notifyDataReload();
  }
}
// xxx.ets
import { ListDataSource } from './ListDataSource';

@Entry
@Component
struct ListExample {
  private arr: ListDataSource = new ListDataSource([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
  @State isLoading: boolean = false;
  build() {
    Column() {
      List({ space: 20, initialIndex: 0 }) {
        LazyForEach(this.arr, (item: number) => {
          ListItem() {
            Text('' + item)
              .width('100%').height(100).fontSize(16)
              .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
          }
        }, (item: number) => item.toString())
      }
      .onReachEnd(() => {
        // 滚动到列表底部时触发加载
        if (!this.isLoading) {
          this.isLoading = true;
        }
        for (let i = 0; i < 6; i++) {
          this.arr.addLastItem()
        }
        this.isLoading = false;

      })
      .friction(0.6)
      .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
      .edgeEffect(EdgeEffect.Spring) // 边缘效果设置为Spring
      .width('90%')
    }
    .width('100%')
    .height('100%')
    .backgroundColor(0xDCDCDC)
    .padding({ top: 5 })
  }
}

更多关于HarmonyOS 鸿蒙Next中懒加载列表问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


当onReachEnd的时候,触发函数,执行网络请求,获取到数据之后一个一个push到lazyforeach渲染的数组底部

鸿蒙Next中懒加载列表使用LazyForEach组件实现。该组件仅渲染可视区域内的列表项,通过延迟创建和销毁来优化性能。开发者需实现数据源接口,包括总项数、获取数据项和创建组件的方法。注意数据源更新需调用LazyForEach的刷新接口。

在HarmonyOS Next中实现懒加载列表结合网络数据获取,关键在于合理管理数据流和页面状态。以下是核心实现方案:

1. 数据层设计

  • 创建ListDataSource类管理数据,包含items(已加载数据)、pageIndex(当前页码)、hasMore(是否有更多数据)等属性
  • 使用@Observed装饰器实现数据变化自动刷新UI

2. 网络请求集成

// 模拟分页请求
async loadMoreData(): Promise<void> {
  if (this.isLoading || !this.hasMore) return;
  
  this.isLoading = true;
  try {
    const newData = await api.fetchListData(this.pageIndex, PAGE_SIZE);
    this.items.push(...newData);
    this.hasMore = newData.length === PAGE_SIZE;
    this.pageIndex++;
  } catch (error) {
    // 错误处理
  } finally {
    this.isLoading = false;
  }
}

3. 列表组件实现

@Entry
@Component
struct LazyList {
  @State dataSource: ListDataSource = new ListDataSource();

  aboutToAppear(): void {
    this.dataSource.loadMoreData();
  }

  build() {
    List({ space: 10 }) {
      ForEach(this.dataSource.items, 
        (item) => {
          ListItem() {
            // 列表项内容
          }
        }
      )
      
      // 加载更多项
      if (this.dataSource.isLoading) {
        ListItem() {
          LoadingProgress()
        }
      }
    }
    .onReachEnd(() => {
      this.dataSource.loadMoreData();
    })
    .scrollBar(BarState.Off)
  }
}

4. 关键优化点

  • 节流处理:在onReachEnd回调中添加防抖逻辑,避免频繁触发
  • 空状态提示:首次加载无数据时显示占位图
  • 错误重试:网络请求失败时提供重试按钮
  • 内存管理:大量数据时考虑虚拟列表方案

5. 性能注意事项

  • 使用ListItemreuseId属性提升复用效率
  • 复杂列表项建议使用@Reusable装饰器
  • 分页大小建议控制在20-50条之间

这种实现方式通过onReachEnd事件监听触底,自动触发下一页数据加载,同时保持UI流畅性。实际开发中还需根据API接口的具体分页协议调整页码处理逻辑。

回到顶部