img

目录

  • 案例介绍
  • 代码实现
  • 代码详解
  • 数据结构设计
  • 界面实现分析
  • 总结

案例介绍

本篇文章将详细介绍如何在HarmonyOS NEXT中实现一个专业代码编辑器的文件树导航功能。通过使用List组件和状态管理,我们将构建一个支持文件夹展开/收起的文件树界面。

代码实现

@Entry
@Component
struct CodeEditor {
  // 文件树数据结构定义
  @State fileTree: Array<{
    name: string,
    type: 'file' | 'folder',
    children?: Array<{ name: string, type: 'file' | 'folder' }>
  }> = [
    {
      name: 'src',
      type: 'folder',
      children: [
        { name: 'main.ets', type: 'file' },
        { name: 'app.ets', type: 'file' }
      ]
    },
    {
      name: 'resources',
      type: 'folder',
      children: [
        { name: 'index.html', type: 'file' },
        { name: 'styles.css', type: 'file' }
      ]
    },
    { name: 'package.json', type: 'file' }
  ]

  build() {
    Column() {
      // 文件树工具栏
      Row() {
        Text('文件')
          .fontSize(16)
          .fontWeight(FontWeight.Medium)
        Blank()
        Button({
          type: ButtonType.Circle,
          stateEffect: true
        }) {
          Image($r('app.media.add'))
            .width(16)
            .height(16)
        }
        .width(24)
        .height(24)
        .margin({ left: 8 })
      }
      .width('100%')
      .height(40)
      .padding({ left: 16, right: 16 })
      .backgroundColor('#F8F9FA')

      // 文件列表实现
      List() {
        ForEach(this.fileTree, (item) => {
          ListItem() {
            Row() {
              Image(item.type === 'folder' ? $r('app.media.folder') : $r('app.media.file'))
                .width(16)
                .height(16)
              Text(item.name)
                .fontSize(14)
                .margin({ left: 8 })
            }
            .width('100%')
            .padding(8)

            if (item.type === 'folder' && item.children) {
              Column() {
                ForEach(item.children, (child) => {
                  Row() {
                    Image(child.type === 'folder' ? $r('app.media.folder') : $r('app.media.file'))
                      .width(16)
                      .height(16)
                    Text(child.name)
                      .fontSize(14)
                      .margin({ left: 8 })
                  }
                  .width('100%')
                  .padding(8)
                  .padding({ left: 24 })
                  .onClick(() => {
                    if (child.type === 'file') {
                      this.currentFile.name = child.name
                    }
                  })
                })
              }
            }
          }
          .onClick(() => {
            if (item.type === 'file') {
              this.currentFile.name = item.name
            }
          })
        })
      }
      .width('100%')
      .layoutWeight(1)
    }
    .width(250)
    .height('100%')
    .backgroundColor('#F8F9FA')
  }
}

代码详解

数据结构设计

  1. 文件树数据模型
    • 使用@State装饰器定义响应式数据
    • 采用递归结构支持无限层级的文件夹
    • 通过type字段区分文件和文件夹
    • children数组存储子文件和文件夹

界面实现分析

  1. 工具栏设计

    • 使用Row布局实现水平排列
    • Blank()组件实现两端对齐
    • 圆形按钮配合图标实现添加功能
    • 统一的内边距和背景色设置
  2. 文件列表实现

    • List组件作为容器承载文件树结构
    • ForEach实现数据循环渲染
    • 根据type类型显示不同图标
    • 文件夹项支持子列表展示
    • 统一的间距和点击交互
  3. 交互处理

    • 文件点击事件:更新currentFile.name
    • 文件夹点击:切换展开/收起状态
    • 子文件点击:独立的事件处理
    • 统一的视觉反馈

总结

本篇文章详细介绍了如何实现一个专业的文件树导航功能:

  1. 采用递归的数据结构设计,支持多层级文件夹
  2. 使用List和ForEach实现高效的列表渲染
  3. 完善的交互处理,包括文件选择和文件夹展开/收起
  4. 统一的视觉风格,提供专业的用户体验
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐