路线列表页与LazyForEach

鸿蒙原生开发手记:徒步迹 - 路线列表页与@LazyForEach

使用 @LazyForEach 实现高性能长列表


一、前言

路线列表是用户浏览路线的入口。当路线数据量大时,使用 @LazyForEach 进行懒加载可以显著提升性能。


二、@LazyForEach 基础

2.1 原理

@LazyForEach 只渲染可见区域的列表项,离屏的列表项会被回收,大幅减少内存占用。

2.2 使用步骤

// 1. 定义数据源(实现 IDataSource 接口)
class RouteDataSource implements IDataSource {
  private data: HikingRoute[] = [];

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

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

  registerDataChangeListener(listener: DataChangeListener): void {}
  unregisterDataChangeListener(listener: DataChangeListener): void {}
}

// 2. 创建数据源实例
@State private dataSource: RouteDataSource = new RouteDataSource();

// 3. 在 @LazyForEach 中使用
@LazyForEach(this.dataSource, (item: HikingRoute) => {
  ListItem() {
    RouteCard({ route: item });
  }
}, (item: HikingRoute) => item.id.toString());

三、完整路线列表实现

// 数据源
class RouteDataSource extends ArrayList<HikingRoute> {
  // 实现 IDataSource 接口的方法...
}

@Entry
@Component
struct RouteListPage {
  @State private dataSource: RouteDataSource = new RouteDataSource();
  @State private currentPage: number = 1;
  private listScroller: Scroller = new Scroller();

  aboutToAppear(): void {
    this.loadRoutes();
  }

  build() {
    Column() {
      // 顶部导航
      Row() {
        Text('路线列表')
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .layoutWeight(1)
          .textAlign(TextAlign.Center);
      }
      .width('100%')
      .padding(16);

      // 搜索框
      SearchBar();

      // 懒加载列表
      List() {
        LazyForEach(this.dataSource, (route: HikingRoute) => {
          ListItem() {
            RouteCard({
              route: route,
              onClick: () => {
                router.pushUrl({
                  url: 'pages/RouteDetailPage',
                  params: { routeId: route.id },
                });
              },
            });
          }
        }, (route: HikingRoute) => route.id.toString());
      }
      .width('100%')
      .layoutWeight(1)
      .onReachEnd(() => {
        // 触底加载更多
        this.loadMore();
      });
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5');
  }

  async loadRoutes(): Promise<void> {
    const response = await apiService.getRoutes(this.currentPage, 10);
    // 添加到数据源...
  }

  loadMore(): void {
    this.currentPage++;
    this.loadRoutes();
  }
}

四、性能优化建议

  1. 固定 Item 高度:给 ListItem 设置固定高度
  2. 减少重绘:避免在列表项中使用复杂动画
  3. 合理设置缓存cachedCount(5) 设置预渲染的项数

五、总结

@LazyForEach 是处理大规模列表的关键工具,让路线列表页可以流畅滚动。配合触底分页加载,用户体验良好。

下一篇文章实现路线搜索与筛选功能。


下一篇预告:鸿蒙原生开发手记:徒步迹 - 路线搜索与筛选功能

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐