HarmonyOS 如何实现可折叠的list?

如题:HarmonyOS 如何实现可折叠的list?

阅读 469
1 个回答

参考示例demo如下:

Index.ets页面

import MyDataSource from './model/MyDataSource'
@Observed
class TimeTable {
  title: string;
  projects: string[];
  constructor(title: string, projects: string[]) {
    this.title = title
    this.projects = projects
  }
}

@Entry
@Component
struct ListItemGroupExample {
  @State timeTableList: MyDataSource<TimeTable> = new MyDataSource()

  aboutToAppear() {
    let data1 = new TimeTable("星期一", ['语文', '数学', '英语'])
    let data2 = new TimeTable("星期二", ['物理', '化学', '生物'])
    this.timeTableList.pushData(data1)
    this.timeTableList.pushData(data2)
  }

  build() {
    Column() {
      List({ space: 20 }) {
        LazyForEach(this.timeTableList, (item: TimeTable, index?: number) => {
          ListItem({ style: ListItemStyle.CARD }) {
            ChildList({ data: item, index: index })
          }
        }, (item: TimeTable) => item.title)
      }
      .width('90%')
      .height("100%")
      .scrollBar(BarState.Off)
    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
  }
}

@Component
struct ChildList {
  @ObjectLink data: TimeTable
  @Prop index: number
  @State itemHeight: number = 100
  @State projects: MyDataSource<string> = new MyDataSource()
  @State text: string = ""

  aboutToAppear() {
    this.data.projects.forEach((item: string) => {
      this.projects.pushData(item)
    })
  }

  build() {
    Column() {
      // header
      Row() {
        Text(this.data.title)
          .fontSize(20)
          .padding(10)
        Row() {
          Button(this.itemHeight ? "收起" : "展开")
            .fontSize(12)
            .onClick(() => {
              this.itemHeight = this.itemHeight ? 0 : 100
            })
        }
      }.width("100%").justifyContent(FlexAlign.SpaceBetween)
      .backgroundColor(0xAABBCC)

      List() {
        LazyForEach(this.projects, (item: string, index: number) => {
          ListItem() {
            Row() {
              Text(item)
                .fontSize(20)
                .textAlign(TextAlign.Center)
            }
            .width("100%")
            .justifyContent(FlexAlign.Center)
            .height(this.itemHeight)
            .animation({ duration: 300, iterations: 1 })
            .backgroundColor(0xFFFFFF)
          }
        })
      }
      .width("100%")
      .scrollBar(BarState.Off)
    }
  }
}

pages下model中的MyDataSource.ets

import BasicDataSource from './BasicDataSource';
export default class MyDataSource<T> extends BasicDataSource<T> {
  private dataArray: Array<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);
  }
}

pages下model中的BasicDataSource.ets页面

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

  public totalCount(): number {
    return 0;
  }

  public getData(index: number): T {
    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组件需要在index对应索引处添加子组件
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
    })
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进