HarmonyOS鸿蒙Next中如何实现ListItemGroup中item单独刷新

HarmonyOS鸿蒙Next中如何实现ListItemGroup中item单独刷新

使用中发现不能对ListItemGroup中item单独进行刷新,有没有办法对单条item刷新?

3 回复

开发者您好,框架提供了@Observed@ObjectLink机制进行深度观测,可以做到仅刷新使用了该属性的组件,提高渲染性能。可以使用这套机制来实现ListItemGroup中item单独刷新。下面是示例代码:

@Observed
class Group {
  label: string
  data: DataArray

  constructor(label: string, data: Data[]) {
    this.label = label;
    this.data = data;
  }
}

@Observed
class DataArray extends Array<Data> {
}

@Observed
class Data {
  id: string
  name: string

  constructor(id: string, name: string) {
    this.id = id;
    this.name = name;
  }
}

class BasicDataSource implements IDataSource {
  private listeners: DataChangeListener[] = [];
  originDataArray: Group[] = [];

  public totalCount(): number {
    return 0;
  }

  public getData(index: number): Group {
    return this.originDataArray[index];
  }

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

  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      console.info('remove listener');
      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);
    })
  }

  notifyDatasetChange(operations: DataOperation[]): void {
    this.listeners.forEach(listener => {
      listener.onDatasetChange(operations);
    })
  }
}

class MyDataSource extends BasicDataSource {
  dataArray: Group[] = [];

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

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

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

  public modifyData() {
    this.notifyDataReload()
  }
}

@Entry
@Component
struct Index {
  data: MyDataSource = new MyDataSource();

  aboutToAppear(): void {
    this.data.dataArray.push(...[
      new Group("first Group", [
        new Data('1', 'a'),
        new Data('2', 'b'),
        new Data('3', 'a'),
        new Data('4', 'b'),
        new Data('5', 'a'),
        new Data('6', 'b'),
        new Data('7', 'a'),
        new Data('8', 'b'),
      ]),
      new Group("second Group", [new Data('1', 'c'), new Data('2', 'd')])
    ])
  }

  build() {
    Column() {
      List() {
        LazyForEach(this.data, (group: Group) => {
          MyListGroup({
            group: group
          })
        }, (group: Group) => group.label)
      }
      .sticky(StickyStyle.Header)
    }
    .height('100%')
    .width('100%')
  }
}

@Component
struct MyListGroup {
  @ObjectLink group: Group

  @Builder
  header(name: string) {
    Column() {
      Text(name)
    }
    .width("100%")
    .height(100)
    .backgroundColor(0xAABBCC)
  }

  build() {
    ListItemGroup({ header: this.header(this.group.label) }) {
      ForEach(this.group.data, (item: Data) => {
        MyListItem({ data: item })
      }, (item: Data) => item.id)
    }
  }
}

@Component
struct MyListItem {
  @ObjectLink data: Data

  build() {
    ListItem() {
      Text(this.data.name)
    }
    .width("100%")
    .height(100)
    .backgroundColor(Color.Gray)
    .onClick(() => {
      this.data.name = this.data.name+this.data.name;
    })
  }
}

点击数据项,可以做到数据项单独刷新:

更多关于HarmonyOS鸿蒙Next中如何实现ListItemGroup中item单独刷新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,要实现ListItemGroup中单个item的刷新,可以使用ArkUI的@State@Link装饰器。首先在ListItem的组件中使用@State装饰需要更新的数据,然后在父组件中通过@Link建立双向绑定。当数据变化时,ArkUI框架会自动触发该item的重新渲染。

示例代码片段:

@Entry
@Component
struct ListPage {
  @State items: Array<ItemData> = []

  build() {
    List() {
      ListItemGroup() {
        ForEach(this.items, (item) => {
          ListItem() {
            ItemView({ item: this.items[item.id] })
          }
        })
      }
    }
  }
}

@Component
struct ItemView {
  @Link item: ItemData

  build() {
    Text(this.item.text)
  }
}

修改items数组中特定item的数据即可单独刷新对应ListItem。

在HarmonyOS Next中,可以通过以下方式实现ListItemGroup中单个Item的刷新:

  1. 使用List组件的updateItem方法,通过指定item的index来单独刷新:

    listComponent.updateItem(index, () => {
        // 返回更新后的item数据
        return new YourItemData();
    });
    
  2. 对于ListItemGroup中的item,需要先获取group的index,再获取item在group中的index:

    const groupIndex = ... // 获取group的index
    const itemIndexInGroup = ... // 获取item在group中的index
    
    listComponent.updateItem(groupIndex, (groupData) => {
        // 更新group中特定的item
        groupData.items[itemIndexInGroup] = newItemData;
        return groupData;
    });
    
  3. 另一种方式是使用状态管理,通过@State@Link装饰器标记需要刷新的数据,当数据变化时会自动触发对应item的刷新。

注意:确保在更新数据后调用组件的刷新方法,同时要处理好数据绑定的关系。

回到顶部