img

案例介绍

本教程将介绍如何实现代码编辑器的基础UI组件,包括顶部工具栏、文件树组件和代码编辑区的布局实现。

代码实现

@Entry
@Component
struct CodeEditorPage {
  // 省略数据模型部分...

  @Builder
  FileTree(file: {name: string, type: string, path: string}, level: number = 0) {
    Row() {
      Row() {
        // 缩进
        ForEach(Array(level).fill(0), () => {
          Blank()
            .width(20)
        })
        
        // 文件图标
        if (file.type === 'folder') {
          Image($r('app.media.folder'))
            .width(16)
            .height(16)
            .margin({ right: 8 })
        } else {
          Image($r('app.media.file'))
            .width(16)
            .height(16)
            .margin({ right: 8 })
        }
        
        // 文件名
        Text(file.name)
          .fontSize(14)
      }
      .width('100%')
      .padding({ top: 8, bottom: 8, left: 8, right: 8 })
      .borderRadius(4)
      .backgroundColor(this.currentFile === file.path ? '#E0E0E0' : 'transparent')
      .onClick(() => {
        if (file.type === 'file') {
          this.currentFile = file.path;
        }
      })
    }
    .width('100%')
  }

  build() {
    Column() {
      // 顶部工具栏
      Row() {
        Text('代码编辑器').fontSize(18).fontWeight(FontWeight.Bold)
        Blank()
        Row() {
          Text('主题:').fontSize(14)
          Select([
            { value: 'light', icon: $r('app.media.light') },
            { value: 'dark', icon: $r('app.media.dark') }
          ])
          .selected(this.currentTheme === 'light' ? 0 : 1)
          .value(this.currentTheme)
          .onSelect((index, value) => {
            this.currentTheme = value as string;
          })
          .margin({ right: 16 })

          Text('字体大小:').fontSize(14)
          Select([
            { value: '12', icon: $r('app.media.font_small') },
            { value: '14', icon: $r('app.media.font_medium') },
            { value: '16', icon: $r('app.media.font_large') }
          ])
          .selected(this.fontSize === 14 ? 1 : (this.fontSize === 12 ? 0 : 2))
          .value(this.fontSize.toString())
          .onSelect((index, value) => {
            this.fontSize = parseInt(value as string);
          })
        }
      }
      .width('100%')
      .height(50)
      .padding({ left: 16, right: 16 })
      .backgroundColor('#F2F2F2')

      // 左侧文件树
      Column() {
        Text('项目文件').fontSize(16).fontWeight(FontWeight.Bold).margin({ bottom: 10 })
        List() {
          ForEach(this.files.filter(file => !file.path.includes('/')), (file) => {
            ListItem() {
              if (file.type === 'folder') {
                Column() {
                  this.FileTree(file)
                  // 显示文件夹内的文件
                  Column() {
                    ForEach(this.files.filter(f => f.path.startsWith(file.path + '/')), (subFile) => {
                      this.FileTree(subFile, 1)
                    })
                  }
                  .width('100%')
                }
                .width('100%')
              } else {
                this.FileTree(file)
              }
            }
          })
        }
        .width('100%')
      }
      .width('20%')
      .height('100%')
      .backgroundColor('#F5F5F5')
      .padding(16)
    }
  }
}

代码详解

文件树组件

  1. @Builder装饰器

  2. 缩进实现

    • 使用ForEach和Blank实现缩进
    • 根据level参数控制缩进层级
  3. 文件图标

    • 根据文件类型显示不同图标
    • 设置统一的图标大小和间距
  4. 点击事件

    • 仅文件类型可点击选中
    • 更新currentFile状态

顶部工具栏

  1. 布局设计

    • 使用Row实现水平布局
    • 左侧显示标题
    • 右侧显示主题和字体设置
  2. 主题切换

    • 使用Select组件实现
    • 支持light和dark主题
    • 实时更新主题状态
  3. 字体大小设置

    • 提供三种字体大小选项
    • 使用Select组件实现
    • 动态更新字体大小

文件树列表

  1. 列表实现

    • 使用List和ForEach遍历文件数据
    • 区分文件和文件夹的显示
  2. 文件夹展开

    • 显示文件夹内的文件
    • 使用路径前缀匹配子文件
  3. 样式处理

    • 统一的背景色和内边距
    • 合适的宽度和高度设置

总结

本教程介绍了代码编辑器基础UI组件的实现,包括:

  1. 文件树组件的封装和实现
  2. 顶部工具栏的布局和功能
  3. 文件树列表的渲染和交互

通过这些基础UI组件的实现,我们为代码编辑器提供了良好的用户界面基础。

Logo

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

更多推荐