HarmonyOS 鸿蒙Next:List+lazyforeach,在不断向列表顶端插入数据时保持显示的项不变

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

HarmonyOS 鸿蒙Next:List+lazyforeach,在不断向列表顶端插入数据时保持显示的项不变 每次插入数据,都要插入到数组的头部,使用的是LazyFeach时, 发现每次插入数据时, 列表都会往下移动,我想要实现的效果是,在最上方,数据正常刷新,在中间部位,不会让当前数据向下滚动。有demo吗?

2 回复
class BasicDataSource implements IDataSource {
  private listeners: DataChangeListener[] = [];
  private originDataArray: string[] = [];

  public totalCount(): number {
    return 0;
  }

  public getData(index: number): string {
    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: string[] = [];

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

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

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

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

@Entry
@Component
struct MyComponent {
  private data: MyDataSource = new MyDataSource();
  scrollerForList = new Scroller()
  @State listIndex : number = 0

  aboutToAppear() {
    for (let i = 0; i <= 20; i++) {
      this.data.pushData(`Hello ${i}`)
    }

    setInterval(() => {
      this.data.addData(0,'新增数据')
      //2、调用 scrollToIndex 接口设置当前索引位置,当索引位置为0时,正常刷新。
      if (this.listIndex !== 0) {
        this.scrollerForList.scrollToIndex(this.listIndex + 1)
      }
    }, 1000)
  }

  build() {
    List({ space: 3 ,initialIndex:this.listIndex,scroller:this.scrollerForList}) {
      LazyForEach(this.data, (item: string) => {
        ListItem() {
          Row() {
            Text(item).fontSize(50)
              .onAppear(() => {
                console.info("appear:" + item)
              })
          }.margin({ left: 10, right: 10 })
        }
      }, (item: string) => item)
    }
    //1、通过 onScrollIndex 记录当前索引位置:
    .onScrollIndex((firstIndex: number) => {
      this.listIndex = firstIndex
    })
  }
}

更多关于HarmonyOS 鸿蒙Next:List+lazyforeach,在不断向列表顶端插入数据时保持显示的项不变的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,如果你在使用List组件并通过lazyforeach来渲染列表项,同时需要在列表顶端不断插入数据且保持已显示的项位置不变,可以通过以下方式实现:

鸿蒙的List组件支持多种数据更新模式,包括插入、删除和移动等。为了保持已显示项的位置不变,在顶端插入数据时,应确保列表的滚动位置不被重置。

  1. 使用List组件的滚动位置管理:在插入数据前,记录当前的滚动位置。插入数据后,恢复该滚动位置。鸿蒙提供了相应的API来获取和设置列表的滚动位置。

  2. 数据插入操作:在数据源列表的开头插入新数据,确保数据顺序正确。由于使用了lazyforeach,列表会根据数据源自动更新。

  3. 保持UI响应:在大量数据插入时,考虑使用异步操作或分批插入,以避免UI线程阻塞,影响用户体验。

通过上述方法,你可以在列表顶端插入数据而不影响用户当前查看的列表项位置。确保在数据更新后,正确恢复列表的滚动位置是关键。

如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html

回到顶部