上拉页面时，页面下方部分出现空白，显示异常
=====================

#### 问题现象

上拉页面时，上方组件收缩，下方组件上移，组件下方显示大量空白。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/62/v3/Xi1R_ZlVRP6qhu3MmSVz0Q/zh-cn_image_0000002658913483.png?HW-CC-KV=V1&HW-CC-Date=20260709T134019Z&HW-CC-Expire=86400&HW-CC-Sign=96CBA0679AD61AF74720CFF0F2B4E879970DCD3AE2C65E5159441292235F100E "点击放大")

#### 背景知识

[PanGesture](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-gestures-pangesture)为滑动手势事件，当滑动的最小距离达到设定的最小值时触发滑动手势事件。

#### 问题定位

查看下方组件的设置，发现未根据上方组件的变化动态设置自身的尺寸。

class TimeTableDataSource implements IDataSource {
  private list: TimeTable\[\] = \[\];
  private listeners: DataChangeListener\[\] = \[\];

  constructor(list: TimeTable\[\]) {
    this.list = list;
  }

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

  getData(index: number): TimeTable {
    return this.list\[index\];
  }

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

  _// 通知控制器数据变化_
  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index);
    });
  }

  _// 修改第一个元素_
  public change1stItem(temp: TimeTable): void {
    this.list\[0\] = temp;
    this.notifyDataChange(0);
  }
}

class ProjectsDataSource implements IDataSource {
  private list: string\[\] = \[\];

  constructor(list: string\[\]) {
    this.list = list;
  }

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

  getData(index: number): string {
    return this.list\[index\];
  }

  registerDataChangeListener(): void {
  }

  unregisterDataChangeListener(): void {
  }
}

interface TimeTable {
  title: string;
  projects: string\[\];
}

@Entry
@Component
struct ListItemGroupExample {
  itemGroupArray: TimeTableDataSource = new TimeTableDataSource(\[\]);
  @State show: boolean = true;
  @State textHeight: string = '30%';
  private tuesday: TimeTable = {
    title: '星期二',
    projects: \['物理', '化学', '生物', '历史', '地理'\]
  };

  @Builder
  itemHead(text: string) {
    Text(text)
      .fontSize(20)
      .width('100%')
      .padding(10);
  }

  build() {
    Column() {
      Text('收缩组件')
        .height(this.textHeight)
        .textAlign(TextAlign.Center)
        .width('90%')
        .borderRadius(20)
        .backgroundColor('#f1f3f5');
      List() {
        ListItemGroup({
          header: this.itemHead(this.tuesday.title),
          space: 10
        }) {
          LazyForEach(new ProjectsDataSource(this.tuesday.projects), (project: string) => {
            ListItem() {
              Text(project)
                .width('100%')
                .height(150)
                .fontSize(20)
                .textAlign(TextAlign.Center)
                .backgroundColor('#f1f3f5')
                .borderRadius(20)
            };
          }, (item: string) => item);
        }
      }
      .width('90%')
      .height('70%') _// 列表高度固定，未根据上方组件的变化动态设置自身的尺寸_
      .sticky(StickyStyle.Header | StickyStyle.Footer)
      .scrollBar(BarState.Off);
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.White)
    .padding({ top: 5 })
    .gesture(
      _// 绑定拖动手势_
      PanGesture()
        .onActionStart(() => {
          this.show = !this.show;
         _ // 当触发拖动手势时，根据回调函数修改组件的布局位置信息_
          if (this.show) {
            this.textHeight = '30%';
          } else {
            this.textHeight = '5%';
          }
        })
    );
  }
}

#### 分析结论

上方组件收缩时，下方组件未动态调整自身尺寸，导致页面部分空白。

#### 修改建议

上方组件收缩时，下方组件动态调整自身尺寸。

import { ProjectsDataSource, TimeTable, TimeTableDataSource } from '../utils/ListDataSource';

@Entry
@Component
struct ListItemGroupExample {
  itemGroupArray: TimeTableDataSource = new TimeTableDataSource(\[\]);
  @State show: boolean = true;
  @State textHeight: string = '30%';
  @State listHeight: string = '70%';
  private tuesday: TimeTable = {
    title: '星期二',
    projects: \['物理', '化学', '生物', '历史', '地理'\]
  };

  @Builder
  itemHead(text: string) {
    Text(text)
      .fontSize(20)
      .backgroundColor('#f1f3f5')
      .width('100%')
      .padding(10);
  }

  @Builder
  itemFoot(num: number) {
    Text('共' + num + '节课')
      .fontSize(16)
      .backgroundColor(0xAABBCC)
      .width('100%')
      .padding(5);
  }

  build() {
    Column() {
      Text()
        .height(this.textHeight)
        .width('100%')
        .backgroundColor('#ccffff');
      List({ space: 20 }) {
        ListItemGroup({
          header: this.itemHead(this.tuesday.title),
          footer: this.itemFoot(this.tuesday.projects.length)
        }) {
          LazyForEach(new ProjectsDataSource(this.tuesday.projects), (project: string) => {
            ListItem() {
              Text(project)
                .width('100%')
                .height(150)
                .fontSize(20)
                .textAlign(TextAlign.Center)
                .backgroundColor(0xFFFFFF);
            };
          }, (item: string) => item);
        }
        .divider({ strokeWidth: 1, color: '#f1f3f5' }); _// 每行之间的分界线_
      }
      .width('100%')
      .height(this.listHeight)
      .sticky(StickyStyle.Header | StickyStyle.Footer)
      .scrollBar(BarState.Off);
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.White)
    .padding({ top: 5 })
    .gesture(
     _ // 绑定拖动手势_
      PanGesture()
        .onActionStart(() => {
          this.show = !this.show;
          if (this.show) {
            this.textHeight = '30%';
            this.listHeight = '70%';
          } else {
            this.textHeight = '5%';
            this.listHeight = '95%'; _// 上方组件收缩时，下方组件动态调整自身尺寸_
          }
        })
      _// 当触发拖动手势时，根据回调函数修改组件的布局位置信息_
    );
  }
}

src/main/ets/utils/ListDataSource.ets：

export class TimeTableDataSource implements IDataSource {
  private list: TimeTable\[\] = \[\];
  private listeners: DataChangeListener\[\] = \[\];

  constructor(list: TimeTable\[\]) {
    this.list = list;
  }

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

  getData(index: number): TimeTable {
    return this.list\[index\];
  }

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

 _ // 通知控制器数据变化_
  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index);
    });
  }

 _ // 修改第一个元素_
  public change1stItem(temp: TimeTable): void {
    this.list\[0\] = temp;
    this.notifyDataChange(0);
  }
}

export class ProjectsDataSource implements IDataSource {
  private list: string\[\] = \[\];

  constructor(list: string\[\]) {
    this.list = list;
  }

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

  getData(index: number): string {
    return this.list\[index\];
  }

  registerDataChangeListener(): void {
  }

  unregisterDataChangeListener(): void {
  }
}

export interface TimeTable {
  title: string;
  projects: string\[\];
}

效果图如下：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/22/v3/caOW8XtjRbeU31ew4FvJAQ/zh-cn_image_0000002658793531.png?HW-CC-KV=V1&HW-CC-Date=20260709T134019Z&HW-CC-Expire=86400&HW-CC-Sign=460C95644FE51EF499F9C9E4B59E0E9D4235EBB89ECA43083D37D4D538A1C9B3 "点击放大")