HarmonyOS 鸿蒙Next中List懒加载更新问题

发布于 1周前 作者 caililin 来自 鸿蒙OS

HarmonyOS 鸿蒙Next中List懒加载更新问题 List 使用 LazyForEach 加载数据,数据更新后,只有滑动列表,并且 ListItem 滑出屏幕后 ,UI 才更新。请教下这是为啥?我该怎么修改? demo 如下:

@Entry
@Component
struct Index {
  @State entryHapRouter: NavPathStack = new NavPathStack()
  listData: string[] = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"]
  newData: string[] = ['100', '101', "102", "103", "104", "105", "106", "107", "108", "109", "110", "111", "112", "113"]
  data: LazyDataSource<string> = new LazyDataSource()
  @State isRefreshing: boolean = false

  @Builder
  header() {
    Row() {
      Text("Header").fontColor(Color.White)
    }.backgroundColor(Color.Gray).width('100%').height(40)
  }

  build() {
    Navigation(this.entryHapRouter) {
      Refresh({ refreshing: this.isRefreshing }) {
        Column() {
          List() {
            ListItemGroup({ header: this.header() }) {
              LazyForEach(this.data, (item: string) => {
                ListItem() {
                  Text(item)
                }.width('100%').height(100).backgroundColor(Color.Orange)
              })
            }.divider({ strokeWidth: 1, color: Color.White })
          }
          .sticky(StickyStyle.Header)
          .listDirection(Axis.Vertical) // 排列方向
          .scrollBar(BarState.Off)
          .friction(0.6)
          .edgeEffect(EdgeEffect.None) // 边缘效果设置为Spring
          .nestedScroll({ scrollForward: NestedScrollMode.PARENT_FIRST, scrollBackward: NestedScrollMode.PARENT_FIRST })
        }
      }.onRefreshing(() => {
        setTimeout(() => {
          this.data.pushArrayData(this.newData)
          this.isRefreshing = false
        }, 2000)
      })
    }.hideTitleBar(true).hideBackButton(true).hideToolBar(true).hideToolBar(true)
  }

  aboutToAppear() {
    this.data.pushArrayData(this.listData)
  };
}
// ``` LazyDataSource ```
// import { ObservedArray } from './ObservedArray'

const TAG = '[BasicDataSource]';

export class BasicDataSource<T> implements IDataSource {
  private listeners: DataChangeListener[] = [];

  public totalCount(): number {
    return 0;
  }

  public getData(index: number): T | undefined {
    return undefined;
  }

  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);
    }
  }

  notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded();
    })
  }

  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
    })
  }

  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index);
    })
  }

  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index);
    })
  }

  notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMove(from, to);
    })
  }
}

@Observed
export default class LazyDataSource<T> extends BasicDataSource<T> {
  dataArray: T[] = [];

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

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

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

  public pushData(data: T): void {
    this.dataArray.push(data);
    this.notifyDataAdd(this.dataArray.length - 1);
  }

  public pushArrayData(newData: ObservedArray<T>): void {
    this.clear();
    this.dataArray.push(...newData);
    this.notifyDataReload();
  }

  public appendArrayData(addData: ObservedArray<T>): void {
    this.dataArray.push(...addData);
    this.notifyDataReload();
  }

  public deleteData(index: number): void {
    this.dataArray.splice(index, 1);
    this.notifyDataDelete(index);
  }

  public getDataList(): ObservedArray<T> {
    return this.dataArray;
  }

  public clear(): void {
    this.dataArray.splice(0, this.dataArray?.length);
  }

  public isEmpty(): boolean {
    return this.dataArray.length === 0;
  }
}

// ``` ObservedArray ``` @
Observed
export class ObservedArray<T> extends Array<T> {
  constructor(args?: T[]) {
    if (args instanceof Array) {
      super(...args);
    } else {
      super();
    }
  }
}

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

3 回复

lazyforeach加个key,你这个key值重复了:

LazyForEach(this.data, (item: string, index: number) => {
  ListItem() {
    Text(item)
  }.width('100%').height(100).backgroundColor(Color.Orange)
}, (item: string, index: number) => {
  return item + index
})

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


在HarmonyOS鸿蒙Next中,List组件的懒加载更新主要涉及到数据动态加载和界面渲染的优化。List组件通过LazyForEachForEach实现数据的动态绑定和渲染。LazyForEach适用于大数据量的场景,它仅在需要时创建和渲染子组件,从而提升性能。

在懒加载更新过程中,当数据源发生变化时,List组件会自动触发重新渲染。为了确保更新正确,开发者需要确保数据源的变更能够被List组件感知。通常,可以通过@State@Link@Observed等装饰器来管理数据源的状态变化。

如果遇到懒加载更新不生效的问题,可能的原因包括:

  1. 数据源未正确更新或未触发状态变更。
  2. List组件的键值(key)未正确设置,导致组件无法识别数据变化。
  3. 使用了不支持动态更新的数据结构,如普通数组而非@Observed装饰的对象。

解决这些问题的关键在于确保数据源的状态变更能够被正确触发,并且List组件能够感知到这些变更。

在HarmonyOS的鸿蒙Next中,处理List的懒加载更新时,可以通过LazyForEach组件实现高效渲染。LazyForEach仅在列表项可见时才创建组件,避免不必要的资源消耗。数据源更新时,使用@Observed@ObjectLink装饰器确保UI自动刷新。此外,可以通过onAppearonDisappear回调处理数据的加载与释放,优化性能。建议结合DataSource类管理数据,确保数据变化时列表能高效更新。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!