鸿蒙HarmonyOS之使用ArkTs语言实现层级树状目录选择UI

一、实现效果

在这里插入图片描述
在这里插入图片描述

二、实现步骤

代码示例中用到的颜色、图片等资源可以自行替换设置

1、Index.ets 里面调用

import { CategoryView} from './CategoryView';

//主页面
@Entry
@Component
struct Index {

  @State tabsIndex: number = 0;

  build() {
  		...
  		//层级目录View
        CategoryView()
        ...
  }   
}

3、DirectoryItem.ets 目录数据存储对象

//目录Item
@Observed
export class DirectoryItem {
  id: string = ""; //id
  name: string = ""; //名称
  type: number;//类型:几级目录
  children: DirectoryItem[]; //子目录
  isExpand: boolean = false;

  constructor(id: string, name: string,type: number, children?: DirectoryItem[]) {
    this.id = id;
    this.name = name;
    this.type = type;
    this.children = children || [];
  }
}

3、DirectoryData.ets 目录示例数据

import { DirectoryItem } from '../bean/DirectoryItem';

//目录数据
export const directoryStructure: DirectoryItem[] = [

  new DirectoryItem('1','默认目录1',1, [

    new DirectoryItem('2','1.1',2, [
      new DirectoryItem('3','1.1.1',3),
      new DirectoryItem('4','1.1.2',3, [new DirectoryItem('5','(1)',4), new DirectoryItem('6','(2)',4)]),
      new DirectoryItem('7','1.1.3',3)]),

    new DirectoryItem('8','1.2',2),

    new DirectoryItem('9','1.3',2, [new DirectoryItem('10','1.3.1',3), new DirectoryItem('11','1.3.2',3)])

  ])

];

4、CategoryView.ets 目录UI

import { DirectoryItem } from '../bean/DirectoryItem'
import { directoryStructure } from '../data/DirectoryData'

//云传页
@Preview
@Component
export struct Tab_CloudUploadContent {
  build() {
    Column() {
      Row() {
        Text($r('目录'))
          .fontSize(30)
          .fontFamily('HarmonyHeiTi-Medium')
          .fontColor($r('app.color.font_color_dark'))
      }
      .width('100%')
      .height(80)

      //选择目录UI
      if (directoryStructure.length > 0){
        List() {
          ForEach(directoryStructure, (data: DirectoryItem, index: number) => {
            ListItem() {
              DirectoryComponent({ item: directoryStructure[index] })
            }
          })
        }
        .width('100%')
        .height('100%')
        .padding({ left: 10, right: 10 })
        .divider({ strokeWidth: 1, color: $r('app.color.background_shallow_grey') })
      }
    }
    .width('100%')
    .height('100%')
    .padding(10)
  }
}

//目录组件
@Component
struct DirectoryComponent {
  @ObjectLink item: DirectoryItem; //当前目录Item对象
  @State selectId: string = ''; //选中目录Id
  @State isOpen: boolean = false; //记录目录是否展开状态

  build() {
    Column() {
      Row(){
        Row() {
          Text("|")
            .fontSize(15)
            .fontWeight(FontWeight.Bold)
            .fontColor($r('app.color.tab_bar_select'))

          //目录名称
          Text(this.item.name)
            .fontSize(15)
            .fontWeight(FontWeight.Bold)
            .margin({ left: 8 })
            .fontColor($r('app.color.font_color_dark'))
        }
        .layoutWeight(1)
        .margin({ left: (this.item.type - 1) * 20 })

        //目录是否展开图标
        Image(this.isOpen ? $r('app.media.ic_select_live') : $r('app.media.ic_unselect_live'))
          .width('20vp')
          .height('20vp')
          .objectFit(ImageFit.Contain)
      }
      .height(50)
      .width('100%')
      .onClick(() => {
        if (this.item.children != undefined) {
          //打开子目录 更新目录打开状态
          this.item.isExpand = !this.item.isExpand;
          this.isOpen = this.item.isExpand;
        } else {
          //记录选中目录Id
          this.selectId = this.item.id;
        }
      })

      List() {
        ForEach(this.item.children, (children: DirectoryItem,index: number) => {
          ListItem() {
            if (children.children != undefined && children.children.length > 0) {
              //存在子目录,去循环生成层级目录
              DirectoryComponent({item: this.item.children[index]})
            } else {
              //没有子目录了,直接生成单个目录项
              this.renderDirectoryItem(children)
            }
          }
        }, (item: DirectoryItem) => item.name)
      }
      .visibility(this.isOpen ? Visibility.Visible : Visibility.None)
      .width('100%')
      .divider({ strokeWidth: 1, color: $r('app.color.background_shallow_grey') })
    }
  }


  @Builder
  private renderDirectoryItem(item: DirectoryItem) {
    Row() {
      Text(item.name)
        .fontWeight(FontWeight.Bold)
        .fontSize(15)
        .fontColor($r('app.color.font_color_dark'))
        .layoutWeight(1)
        .margin({ left: (item.type - 1) * 20 + 11})
    }
    .width('100%')
    .height('50vp')
    .onClick(() => {
      //记录点击选中目录Id
      this.selectId = item.id;
    })
  }
}

5、预览运行查看index.ets文件即可查看效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值