鸿蒙容器组件(比如List)动态高度简单实现

417 阅读1分钟

需求描述

我们App在Android上有一个UI是弹框中展示List列表,由于List的每个Item的高度不固定同时为了整体美观。UI做出如下要求:

  • List的item小于等于2的时候高度自适应
  • List的item大于2的时候,高度限制为前2个Item之和。

实现细节

  1. 定义list的高度为listHeight: number | string = 'auto',保证初始化时正常加载
  2. 为List以及ListItem定义id标签,在build()方法中对应组件直接.id()就行
  3. 在aboutToAppear()方法中通过inspector.createComponentObserver监听layout事件,在收到第二个item的layout完成事件之后通过componentUtils.getRectangleById方法获得2个item的高度,动态为listHeight赋值。

代码参考

const id_List = 'MultiDialogList';
const id_List_Item = 'MultiDialogListItem';

@Entry(...)
@Component
export struct MultiDialogStruct {
  @LocalStorageProp(storageKey) permissions: Array<PermissionData> = new Array();
  @State listHeight: number | string = 'auto';

  build() {
    ...
    List() {
      ForEach(this.permissions, (item: PermissionData, index) => {
        ListItem() {
          ...
        }
        .id(id_List_Item + index)
      });
        
    }
    .id(id_List)
    .height(this.listHeight)
    ...
  }

  listener: inspector.ComponentObserver = inspector.createComponentObserver(id_List);
  listenerItem: inspector.ComponentObserver = inspector.createComponentObserver(id_List_Item + '1');

  aboutToAppear() {
    if (this.permissions.length > 2) {
      let itemLayoutComplete: boolean = false;
      //list初始化时会回调一次第一个item为0以及List的layout完成。因此需要监听下标为1也就是第二个item的layout完成
      //保证正确处理高度
      this.listener.on('layout', () => {
        if (itemLayoutComplete) {
          let itemOne: componentUtils.ComponentInfo = componentUtils.getRectangleById(id_List_Item + '0');
          let itemTwo: componentUtils.ComponentInfo = componentUtils.getRectangleById(id_List_Item + '1');
          if (this.listHeight == 'auto') {
            this.listHeight = px2vp(itemOne.size.height + itemTwo.size.height);
          }
        }
      });

      this.listenerItem.on('layout', () => {
        itemLayoutComplete = true;
      });
    }
  }

  aboutToDisappear(): void {
    this.listener.off('layout');
    this.listenerItem.off('layout');
  }
}

参考链接

docs.openharmony.cn/pages/v4.0/…