鸿蒙项目开发中,层级结构的选择很常见,API9没有直接可以使用的层级结构,那么就自己搞一个。

1.话不多说,先展示样式

HarmonyOS应用开发实战-API 9 实现层级(树形)结构_鸿蒙

2.设计思路

其实主要是List的使用,主要的点在,点击更改实体类中是否折叠属性值,更改数据源后动态刷新UI。

3.具体代码

import prompt from '@ohos.promptAction';
import Constants from '../common/Constants';
import TitleBar from '../view/TitleBar';
import { FangWuAddressBean } from '../bean/FangWuAddressBean';
import showToast from '../utils/ToastUtils';

/**
 * @description 房屋地址
 * @author Gwei
 * @time 2024/3/7 14:24
 */
@Entry
@Component
struct FangWuAddressPage {
  @State title: string = '房屋地址';
  @State listData: Array<FangWuAddressBean> = [];

  aboutToAppear() {
    let NoticeData3: Array<FangWuAddressBean> = [];
    let NoticeData2: Array<FangWuAddressBean> = [
      new FangWuAddressBean('05', 'sub2层', '3', NoticeData3)
    ];
    let NoticeData: Array<FangWuAddressBean> = [
      new FangWuAddressBean('04', 'sub1层', '2', NoticeData2)
    ];

    let NoticeData6: Array<FangWuAddressBean> = [];
    let NoticeData5: Array<FangWuAddressBean> = [
      new FangWuAddressBean('07', 'subsub2层', '3', NoticeData6)
    ];
    let NoticeData4: Array<FangWuAddressBean> = [
      new FangWuAddressBean('06', 'subsub1层', '2', NoticeData5)
    ];


    let NoticeData9: Array<FangWuAddressBean> = [];
    let NoticeData8: Array<FangWuAddressBean> = [
      new FangWuAddressBean('09', 'subsubsub2层', '3', NoticeData9)
    ];
    let NoticeData7: Array<FangWuAddressBean> = [
      new FangWuAddressBean('08', 'subsubsub1层', '2', NoticeData8)
    ];

    this.listData.push(new FangWuAddressBean('01', '一层', '1', NoticeData), new FangWuAddressBean('02', '二层', '1', NoticeData4), new FangWuAddressBean('03', '三层', '1', NoticeData7))
    //获取房屋地址列表
    /*xxcjViewModel.getFangWuAddressList((result) => {
      this.listData = result.data
    })*/
  }

  build() {
    Column() {

      TitleBar({ title: this.title })

      if (this.listData.length > 0) {
        List() {
          ForEach(this.listData, (data: FangWuAddressBean, index: number) => {
            ListItem() {
              ListCell({ item: this.listData[index] })
            }
          })
        }.width('100%')
        .height('100%')
        .padding({ left: 10, right: 10 })
        .divider({ strokeWidth: 1, color: $r('app.color.liner_color') })
      }
    }
  }
}

@Component
struct ListCell {
  @ObjectLink item: FangWuAddressBean;
  @State selectTxt: string = '';
  @State selectId: string = '';
  @State currentIndex: number = 0;
  @State isChang: boolean = false;

  build() {
    Column() {
      Row() {
        Row() {
          Text("|")
            .fontSize('14fp')
            .fontWeight(FontWeight.Bold)
            .fontColor($r('app.color.colorPrimary'))
          Text(this.item.name)
            .fontWeight(FontWeight.Bold)
            .margin({ left: 8 })
            .fontColor($r('app.color.color_black'))
        }.layoutWeight(1)
        .margin({ left: Number.parseInt(this.item.lev) * 20 })

        Image(this.isChang ? $r('app.media.icon_down') : $r('app.media.icon_more'))
          .width('20vp')
          .height('20vp')
          .objectFit(ImageFit.Contain)
      }
      .height(50)
      .width('100%')
      .backgroundColor($r('app.color.color_white'))
      .onClick(() => {
        if (this.item.subList != undefined) {
          this.item.isExpand = !this.item.isExpand;
          this.isChang = this.item.isExpand;
          showToast('当前点击的id' + this.item.id)
        } else {
          this.selectTxt = this.item.name;
          this.selectId = this.item.id;
          showToast('当前点击的id' + this.item.id)
          /*router.back({
            url: RoutePath.SjsbPage,
            params: {
              data: this.selectTxt,
              id: this.selectId
            }
          });*/
        }
      })

      List() {
        ForEach(this.item.subList, (childItem: FangWuAddressBean, index: number) => {
          ListItem() {
            if (childItem.subList!=undefined && childItem.subList.length > 0) {
              ListCell({ item: this.item.subList[index] })
            } else {
              this.ListChildCell(this.item.name, childItem, index)
            }
          }
        }, (item, NewsBean) => JSON.stringify(item))
      }
      .visibility(this.isChang ? Visibility.Visible : Visibility.None)
      .backgroundColor($r('app.color.color_white'))
      .width('100%')
      .divider({ strokeWidth: 1, color: $r('app.color.liner_color') })
    }
  }

  @Builder
  ListChildCell(parentTitle: string, item: FangWuAddressBean, index: number) {
    Row() {
      Text(item.name)
        .fontSize('14fp')
        .fontColor($r('app.color.tab_default_color'))
        .layoutWeight(1)
        .margin({ left: Number.parseInt(item.lev) * 20 })
    }
    .width('100%')
    .height('50vp')
    .onClick(() => {
      this.selectTxt = parentTitle + "-" + item.name + "-" + item.id;
      this.selectId = item.id;
      prompt.showToast({
        message: this.selectTxt,
        duration: Constants.WebConstant_DURATION
      })
      /*router.back({
        url: RoutePath.SjsbPage,
        params: {
          data: this.selectTxt,
          id: this.selectId
        }
      });*/
    })
  }
}

4.总结

这样就实现了,如果符合大家的需求直接用就好,不满足可以自己稍微调整一下。