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

news2024/12/23 14:41:35

一、实现效果

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

二、实现步骤

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

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文件即可查看效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2056164.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AMD和NVIDIA一起挤牙膏,新显卡性能反而降低

红厂 AMD 因为新品锐龙 9000 CPU,在这两天算是赚足了眼球和关注度。 在两周的延迟后,高端 R9 系列终于是端上来了,R9-9900X 和 R9-9950X,核心规模和最高加速频率与上代保持不变,基础频率略有降低。 国行售价分别为 339…

FFmpeg的入门实践系列一

欢迎诸位来阅读在下的博文~ 在这里,在下会不定期发表一些浅薄的知识和经验,望诸位能与在下多多交流,共同努力! 江山如画,客心如若,欢迎到访,一展风采 文章目录 参考环境本系列的适用人群FFmpeg的简介FFmpeg…

【等保测评】Ngnix模拟测评

一、身份鉴别 a)应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换; 结果记录:此项不适用,Nginx无独立的登录管理界面,身份鉴别由操作系统层面实现 b)应具有登…

基于linux下的mplayer播放器项目

项目名称:基于MPlayer的C语言控制接口 版本:1.0 1. 项目概述 本项目旨在设计一个基于MPlayer的简单C语言控制接口,提供用户与媒体播放器的交互功能。用户可以通过文本菜单选择不同的操作,如播放、暂停、停止、调整播放速度、跳…

MySql 高阶二(SQL 性能分析)

SQL 性能分析: 查看当前数据库的 增删改查的使用情况 show global status like Com_______;慢查询日志: -- 查看状态 show variables like slow_query_log目前是开启状态。如何开启,编辑my.cnf 文件 添加下面的语句,编辑完成后…

【卡码网C++基础课 1.A+B问题1】

文章目录 题目描述与分析一、C函数基础二、输入输出流三、变量四、写入数据五、输出数据六、尝试第一次提交七、循环输入输出八、延伸 题目描述与分析 题目描述: 你的任务是计算ab。 输入描述: 输入包含一系列的a和b对,通过空格隔开。一对a…

《内生性随机边界模型及 Stata 具体操作步骤》

目录 一、文献综述 二、理论原理 三、实证模型 四、稳健性检验 五、程序代码及解释 一、文献综述 自 Aigner 等(1977)、Meeusen 和 van den Broeck(1977)引入随机前沿模型以来,该模型已有 40 多年的历史。它由确定…

【Qt】Qt窗口 | QStatusBar 状态栏

文章目录 一. 状态栏二. 代码创建&使用状态栏1. 创建状态栏2. 在状态栏中显示实时消息3. 在状态栏中显示控件 一. 状态栏 状态栏是应用程序中输出简要信息的区域,通常位于窗口的底部,用于显示应用程序的状态信息或提供用户与应用程序交互的反馈。一…

qt的model view 使用示范

首先在ui界面拖一个tableView ui->tableView->setModel(mission_model); 然后设置model的qss,并用view绑定model void SettingWidget::init_missionmodel(QString plane_type, QString mission_name) {if(mission_model)delete mission_model;mission_model…

《智能计算系统:从深度学习到大模型(第2版)》重磅上市!

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

PINCE——Linux 原生游戏内存修改器,一款替代 Cheat Engine 的强大游戏修改器,Linux 游戏玩家必备神器!

PINCE——Linux 原生游戏内存修改器,一款替代 Cheat Engine 的强大游戏修改器,Linux 游戏玩家必备神器! PINCE 是 GNU Project Debugger(GDB) 的前端/反向工程工具,常用作程序调试器,主要用于游戏领域,修改…

docker容器图形化管理之Portainer

docker容器轻量级图形页面管理之Portainer 1、查看portainer镜像 [rootlocalhost ~]# docker search portainer 2、下载portainer镜像 [rootlocalhost ~]# docker pull portainer/portainer #选择喜欢的portainer风格镜像下载 3、启动dockerui容器 [rootlocalhost ~]# doc…

京东物流开放平台对接云打印功能

这是京东开发文档的流程图,根据自己的需求分析,我选择的是接入方式一 这是接入方式一的流程图: 所有第一步我们先下载他的打印组件并安装:京东物流开放平台 第二步呢就是看你有没有自定义快递面单的需求,由于目前我没有特别的需…

录屏选区指南,优选3款支持区域录制的录屏软件!

在数字内容创作和分享的时代,录屏软件成为了游戏玩家、教育工作者和视频博主的重要工具。无论是想要捕捉精彩的游戏瞬间,还是制作教学视频,选择正确的录屏区域都是确保内容质量和观众体验的关键。然而,面对市面上众多的录屏软件&a…

HDFS回收站-删除策略详解

HDFS拥有回收站的功能,将某一段时间的删除的数据,放到指定路径(/user/{username}/.Trash),至少保留指定的时间,然后一起删除。 现实中发现回收站里有该删除的却没有删除,和回收站原理逻辑对不上。 以下从源码上看看到底是什么原因导致的。 背景 某HDFS集群指定数据保留…

Docusign Maestro:智能自动化,实现无缝协作,让签约更简单!

作为 Docusign IAM 引擎的核心部分,Maestro 能够帮助你自动化、定制并连接你的协议工作流程。你可以完全按照自己的需求,定制每一个流程细节。无论是什么类型的协议,Maestro 都能减少繁琐的手动操作,让最终用户更快、更轻松地完成…

springboot网上商品订单转手系统论文源码调试讲解

第2章 开发环境与技术 开发网上商品订单转手系统需要搭建编程的环境,也需要通过调查,对各个相关技术进行分析,选取适合本系统开发的技术与工具。 2.1 MYSQL数据库 题目确定了是一个应用程序之后,就开始按部就班的进行设计与分析…

7个超有意思的网站,值得收藏起来慢慢用

分享7个超有意思的网站,绝对让你意想不到! 1、动漫捏脸 Picrew|つくってあそべる画像メーカー 一个超有趣的二次元动漫捏脸网站,你可以随意制作自己喜欢的各种动漫形象、头像等画作,搭配B站教程食用更佳哦~ 搭配教…

全场景 真利旧 强运维!麒麟信安打造县域自主创新云办公解决方案

近年来,国家正大力推进信息技术自主创新,减少对外依赖,并在关键行业加速推广和应用自研技术产品。现全国乡镇以上各级党政机关积极响应国家战略指引,全面实施自主创新办公系统建设升级。但在升级过程中,却因设备架构和…

4款AI 生成 PPT的工具,帮你赶上演示文稿的新趋势!

AI 生成 PPT 最大的优势就在于它能够帮助我们提高效率。如果我们自己制作的话就需要花费大量的时间去收集资料、构思布局、设计排版。而现在,有了AI工具,一切就迎刃而解,如果大家需要这样的工具,可以看看这4款。 1、笔灵办公 直通…