HarmonyOS 鸿蒙Next ArKTS(API9)实现Android类似的树形结构列表

HarmonyOS 鸿蒙Next ArKTS(API9)实现Android类似的树形结构列表 鸿蒙项目开发中,层级结构的选择很常见,API9没有直接可以使用的层级结构,那么就自己搞一个。

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

![样式图]

  1. 设计思路

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

  1. 具体代码
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
        }
      });*/
    })
  }
}

更多关于HarmonyOS 鸿蒙Next ArKTS(API9)实现Android类似的树形结构列表的实战教程也可以访问 https://www.itying.com/category-93-b0.html

13 回复

这个虚线,画框的部分

更多关于HarmonyOS 鸿蒙Next ArKTS(API9)实现Android类似的树形结构列表的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


哦哦,看你这实现了。

就是没搞定,才来求助作者的,

HarmonyOS的流畅动画和过渡效果让操作更加顺畅,体验极佳。

父子节点是否可以增加虚线连接,看着比较清晰

你看3楼回帖是你想要的效果?

这里发布了图,我重新评论了,麻烦看下,

在9中很不错了。不过10已经有了相关控件a

嗯嗯,目前没申请到资格,所以想着自己在API9中也尝试了一下。

如果想实现一些个性化,自定义话的内容,也可以在这个基础上扩展和入手。

我看10里面目前不支持传入初始化的数据,并且currentId还存在失真情况。

在HarmonyOS鸿蒙Next ArKTS(API9)中,实现类似Android的树形结构列表可以通过使用List组件和自定义ListItem来实现。首先,创建一个数据模型来表示树形结构的节点,每个节点包含子节点列表。然后,使用List组件来展示树形结构,通过递归的方式动态生成子节点列表。

在ArKTS中,可以通过@State装饰器来管理节点的展开和折叠状态。当用户点击某个节点时,根据节点的展开状态动态更新子节点的显示。以下是一个简化的示例代码:

@Entry
@Component
struct TreeList {
  @State nodes: Array<Node> = [
    {
      name: 'Node 1',
      children: [
        { name: 'Node 1.1', children: [] },
        { name: 'Node 1.2', children: [] }
      ]
    },
    {
      name: 'Node 2',
      children: [
        { name: 'Node 2.1', children: [] },
        { name: 'Node 2.2', children: [] }
      ]
    }
  ];

  build() {
    List({ space: 10 }) {
      ForEach(this.nodes, (node: Node) => {
        ListItem() {
          this.renderNode(node)
        }
      })
    }
  }

  @Builder
  renderNode(node: Node) {
    Column() {
      Text(node.name)
        .onClick(() => {
          node.isExpanded = !node.isExpanded;
        })
      if (node.isExpanded) {
        ForEach(node.children, (child: Node) => {
          this.renderNode(child)
        })
      }
    }
  }
}

interface Node {
  name: string;
  children: Array<Node>;
  isExpanded?: boolean;
}

在这个示例中,TreeList组件展示了树形结构列表,每个节点可以展开或折叠其子节点。通过@State装饰器管理节点的展开状态,点击节点时会切换其展开状态并动态更新子节点的显示。

回到顶部