一、实现效果
二、实现步骤
代码示例中用到的颜色、图片等资源可以自行替换设置
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;
})
}
}