HarmonyOS NEXT 实战:打造效率工具箱的插件化架构

前言

HarmonyExplorer 不仅是一款文件管理应用,还内建了一套效率工具箱,集成二维码、Base64、Hash、JSON 格式化、UUID、时间戳转换、颜色选择等常用开发者工具。工具箱的核心挑战在于如何让工具可插拔、可扩展,同时保持 UI 的统一性。本文将完整讲解 ToolManager 插件化架构、ToolCard 组件设计、各工具实现以及扩展机制,帮助你在鸿蒙项目中构建一套可持续演进的工具箱体系。

提示:本文代码基于 HarmonyOS NEXT(API 12+)ArkTS 严格模式编写,禁用 any 类型与隐式断言,所有工具均遵循统一的 ToolBase 抽象接口,便于横向扩展。

一、工具箱页面设计

1.1 页面布局

工具箱页面(ToolboxPage)采用网格布局,每个工具以 ToolCard 形式展示,顶部提供分类切换 Tab,底部提供搜索入口。整体布局遵循"分类清晰、入口显眼、即点即用"的原则。

  1. 顶部 AppNavigationBar 展示页面标题与搜索按钮
  2. 分类 Tab 横向滚动,覆盖编码、转换、生成、颜色等类别
  3. 工具区使用 Grid 布局,每行展示三个 ToolCard
  4. 点击工具卡片跳转到对应工具详情页

1.2 交互设计

工具交互遵循"输入即输出"的理念,用户在输入框输入内容后,结果实时计算并展示,减少额外点击操作。

  • 输入区支持文本输入与粘贴
  • 输出区支持一键复制与清空
  • 历史记录自动保存到 ToolHistory 模型
  • 支持深浅主题切换,UI 自动适配

提示:实时计算要注意性能,对于 Hash、二维码等耗时操作,建议加入防抖机制,避免频繁触发导致卡顿。

二、ToolManager 插件化架构

2.1 架构设计

ToolManager 是工具箱的核心调度器,采用插件化架构管理所有工具的注册、查询与调用。每个工具实现统一的 ToolBase 接口,由 ToolManager 统一调度。

// tools/ToolBase.ets
export interface ToolContext {
  input: string
  options?: Record<string, string>
}

export interface ToolResult {
  success: boolean
  output: string
  message?: string
}

export abstract class ToolBase {
  id: string = ''
  name: string = ''
  description: string = ''
  category: ToolCategory = ToolCategory.OTHER
  icon: Resource = $r('app.media.ic_tool_default')

  abstract execute(context: ToolContext): Promise<ToolResult>
}

export enum ToolCategory {
  ENCODE = '编码转换',
  GENERATE = '生成工具',
  CONVERT = '格式转换',
  COLOR = '颜色工具',
  OTHER = '其他'
}

2.2 工具注册

ToolManager 在应用启动时统一注册所有工具,维护工具列表与分类索引,支持按分类查询。插件化架构的核心在于工具与调度器解耦,新增工具不影响既有逻辑。

ToolManager 提供的核心方法职责如下表:

方法 入参 作用
register ToolBase 实例 注册新工具
getAll 返回全部工具
getByCategory ToolCategory 按分类筛选
execute id, ToolContext 调用指定工具
// manager/ToolManager.ets
import { ToolBase, ToolCategory, ToolContext, ToolResult } from '../tools/ToolBase'

export class ToolManager {
  private static tools: ToolBase[] = []

  static register(tool: ToolBase): void {
    ToolManager.tools.push(tool)
  }

  static getAll(): ToolBase[] {
    return ToolManager.tools
  }

  static getByCategory(category: ToolCategory): ToolBase[] {
    const result: ToolBase[] = []
    for (const tool of ToolManager.tools) {
      if (tool.category === category) {
        result.push(tool)
      }
    }
    return result
  }

  static async execute(id: string, context: ToolContext): Promise<ToolResult> {
    for (const tool of ToolManager.tools) {
      if (tool.id === id) {
        return await tool.execute(context)
      }
    }
    return { success: false, output: '', message: '工具不存在' }
  }
}

三、ToolCard 组件设计

3.1 组件实现

ToolCard 是工具箱的统一展示单元,绑定 ToolBase 元数据,点击触发路由跳转,视觉上保持卡片风格一致。

// components/ToolCard.ets
@Component
export struct ToolCard {
  @Prop toolId: string
  @Prop toolName: string
  @Prop toolDesc: string
  toolIcon: Resource = $r('app.media.ic_tool_default')
  onTap: (id: string) => void = () => {}

  build() {
    Column({ space: 8 }) {
      Image(this.toolIcon).width(40).height(40)
      Text(this.toolName).fontSize(14).fontWeight(FontWeight.Medium).maxLines(1)
      Text(this.toolDesc).fontSize(11).fontColor('#999999').maxLines(2)
    }
    .width('100%')
    .padding(12)
    .backgroundColor('#FFFFFF')
    .borderRadius(16)
    .alignItems(HorizontalAlign.Center)
    .onClick(() => this.onTap(this.toolId))
  }
}

四、工具分类管理

4.1 分类策略

工具按用途分为四类,分类标签与图标色相区分,方便用户快速定位。下表展示了工具与分类的归属关系:

工具名称 所属分类 核心能力
QRCodeTool 生成工具 文本生成二维码
Base64Tool 编码转换 编解码 Base64
HashTool 编码转换 MD5/SHA 哈希计算
JsonTool 格式转换 JSON 美化与压缩
UUIDTool 生成工具 生成 UUID
TimestampTool 格式转换 时间戳与日期互转
ColorTool 颜色工具 颜色选择与转换

提示:分类设计要兼顾扩展性,新增工具时优先归入已有分类,避免分类碎片化影响查找效率。

五、二维码工具(QRCodeTool)

5.1 实现

QRCodeTool 将用户输入的文本生成二维码图片,基于系统提供的二维码生成能力,结果以 PixelMap 形式输出展示。二维码生成是工具箱中使用频率最高的功能之一,需保证生成的清晰度与识别率。

// tools/QRCodeTool.ets
import { ToolBase, ToolContext, ToolResult, ToolCategory } from './ToolBase'
import { QrCode } from '@kit.ScanKit'

export class QRCodeTool extends ToolBase {
  id: string = 'qrcode'
  name: string = '二维码生成'
  description: string = '将文本转换为二维码图片'
  category: ToolCategory = ToolCategory.GENERATE

  async execute(context: ToolContext): Promise<ToolResult> {
    const input: string = context.input.trim()
    if (input.length === 0) {
      return { success: false, output: '', message: '输入内容不能为空' }
    }
    try {
      const pixelMap: PixelMap = QrCode.generatePixelMap(input, 320, 320, 3)
      return { success: true, output: '生成成功', message: 'pixelMap' }
    } catch (e) {
      return { success: false, output: '', message: '二维码生成失败' }
    }
  }
}

六、Base64 工具(Base64Tool)

6.1 实现

Base64Tool 支持编码与解码双向操作,通过 options 中的 mode 字段切换方向,底层使用 buffer 模块完成转换。

// tools/Base64Tool.ets
import { ToolBase, ToolContext, ToolResult, ToolCategory } from './ToolBase'
import { buffer } from '@kit.ArkTS'

export class Base64Tool extends ToolBase {
  id: string = 'base64'
  name: string = 'Base64 编解码'
  description: string = 'Base64 编码与解码'
  category: ToolCategory = ToolCategory.ENCODE

  async execute(context: ToolContext): Promise<ToolResult> {
    const mode: string = context.options?.['mode'] ?? 'encode'
    const input: string = context.input
    try {
      if (mode === 'encode') {
        const encoded: string = buffer.from(input, 'utf-8').toString('base64')
        return { success: true, output: encoded }
      }
      const decoded: string = buffer.from(input, 'base64').toString('utf-8')
      return { success: true, output: decoded }
    } catch (e) {
      return { success: false, output: '', message: 'Base64 转换失败' }
    }
  }
}

七、Hash 工具(HashTool)

7.1 实现

HashTool 支持 MD5、SHA-256 等常用哈希算法,通过 crypto 框架完成摘要计算,适用于校验文件完整性等场景。

// tools/HashTool.ets
import { ToolBase, ToolContext, ToolResult, ToolCategory } from './ToolBase'
import { cryptoFramework } from '@kit.CryptoArchitectureKit'

export class HashTool extends ToolBase {
  id: string = 'hash'
  name: string = '哈希计算'
  description: string = 'MD5/SHA-256 哈希摘要'
  category: ToolCategory = ToolCategory.ENCODE

  async execute(context: ToolContext): Promise<ToolResult> {
    const algo: string = context.options?.['algo'] ?? 'MD5'
    const input: string = context.input
    try {
      const md: cryptoFramework.Md = cryptoFramework.createMd(algo)
      const data: cryptoFramework.DataBlob = { data: new TextEncoder().encodeInto(input) }
      md.updateSync(data)
      const result: cryptoFramework.DataBlob = md.digestSync()
      const hex: string = HashTool.toHex(result.data)
      return { success: true, output: hex }
    } catch (e) {
      return { success: false, output: '', message: '哈希计算失败' }
    }
  }

  static toHex(bytes: Uint8Array): string {
    let hex: string = ''
    for (const b of bytes) {
      const part: string = b.toString(16).padStart(2, '0')
      hex = hex + part
    }
    return hex
  }
}

八、JSON 格式化工具(JsonTool)

8.1 实现

JsonTool 支持美化与压缩两种模式,美化模式按缩进展示,压缩模式移除空白字符,便于在不同场景下使用。

// tools/JsonTool.ets
import { ToolBase, ToolContext, ToolResult, ToolCategory } from './ToolBase'

export class JsonTool extends ToolBase {
  id: string = 'json'
  name: string = 'JSON 格式化'
  description: string = 'JSON 美化与压缩'
  category: ToolCategory = ToolCategory.CONVERT

  async execute(context: ToolContext): Promise<ToolResult> {
    const mode: string = context.options?.['mode'] ?? 'beautify'
    const input: string = context.input.trim()
    try {
      const parsed: Record<string, Object> = JSON.parse(input)
      const space: number = mode === 'beautify' ? 2 : 0
      const output: string = JSON.stringify(parsed, null, space)
      return { success: true, output: output }
    } catch (e) {
      return { success: false, output: '', message: 'JSON 格式错误' }
    }
  }
}

九、UUID 与时间戳工具

9.1 UUIDTool

UUIDTool 生成符合 RFC 4122 标准的 UUID,支持一次性生成多个,便于批量使用。

// tools/UUIDTool.ets
import { ToolBase, ToolContext, ToolResult, ToolCategory } from './ToolBase'
import { util } from '@kit.ArkTS'

export class UUIDTool extends ToolBase {
  id: string = 'uuid'
  name: string = 'UUID 生成'
  description: string = '生成唯一标识符'
  category: ToolCategory = ToolCategory.GENERATE

  async execute(context: ToolContext): Promise<ToolResult> {
    const count: number = Number(context.options?.['count'] ?? '1')
    const list: string[] = []
    for (let i: number = 0; i < count; i++) {
      const uuid: string = util.generateRandomUUID(false)
      list.push(uuid)
    }
    return { success: true, output: list.join('\n') }
  }
}

9.2 TimestampTool

TimestampTool 支持时间戳转日期与日期转时间戳双向操作,是开发调试中的高频工具。

// tools/TimestampTool.ets
import { ToolBase, ToolContext, ToolResult, ToolCategory } from './ToolBase'

export class TimestampTool extends ToolBase {
  id: string = 'timestamp'
  name: string = '时间戳转换'
  description: string = '时间戳与日期互转'
  category: ToolCategory = ToolCategory.CONVERT

  async execute(context: ToolContext): Promise<ToolResult> {
    const mode: string = context.options?.['mode'] ?? 'toDate'
    const input: string = context.input.trim()
    try {
      if (mode === 'toDate') {
        const ts: number = Number(input)
        const date: Date = new Date(ts)
        return { success: true, output: date.toLocaleString() }
      }
      const date: Date = new Date(input)
      return { success: true, output: date.getTime().toString() }
    } catch (e) {
      return { success: false, output: '', message: '时间转换失败' }
    }
  }
}

十、颜色选择器(ColorTool)

10.1 实现

ColorTool 提供颜色选择面板,支持 HEX、RGB、HSV 多种格式互转,并展示颜色预览,方便 UI 开发取色。

// tools/ColorTool.ets
import { ToolBase, ToolContext, ToolResult, ToolCategory } from './ToolBase'

export class ColorTool extends ToolBase {
  id: string = 'color'
  name: string = '颜色选择器'
  description: string = '颜色格式转换与取色'
  category: ToolCategory = ToolCategory.COLOR

  async execute(context: ToolContext): Promise<ToolResult> {
    const hex: string = context.input.trim()
    const rgb: string = ColorTool.hexToRgb(hex)
    if (rgb.length === 0) {
      return { success: false, output: '', message: '颜色格式无效' }
    }
    return { success: true, output: rgb }
  }

  static hexToRgb(hex: string): string {
    if (hex.length !== 7 || hex.charAt(0) !== '#') {
      return ''
    }
    const r: number = parseInt(hex.substring(1, 3), 16)
    const g: number = parseInt(hex.substring(3, 5), 16)
    const b: number = parseInt(hex.substring(5, 7), 16)
    return 'rgb(' + r.toString() + ', ' + g.toString() + ', ' + b.toString() + ')'
  }
}

颜色格式转换规则如下表,ColorTool 内置完整映射逻辑:

输入格式 输出格式 转换说明
#RRGGBB rgb(r,g,b) 十六进制转十进制
rgb(r,g,b) #RRGGBB 十进制转十六进制
#RRGGBB hsv(h,s,v) HEX 转 HSV

在这里插入图片描述

上图展示了工具箱页面的整体视觉效果,分类 Tab 与工具卡片网格配合,形成清晰的导航层级。

十一、工具扩展机制设计

11.1 扩展规范

工具箱的扩展性是其核心价值,新增工具只需三步即可接入,无需修改 ToolManager 主逻辑。良好的扩展机制是工具箱长期演进的根本保障

  1. 新建工具类继承 ToolBase,实现 execute 方法
  2. 在 ToolManager 初始化时调用 register 注册
  3. 在路由表中配置工具详情页
// manager/ToolBootstrap.ets
import { ToolManager } from './ToolManager'
import { QRCodeTool } from '../tools/QRCodeTool'
import { Base64Tool } from '../tools/Base64Tool'
import { HashTool } from '../tools/HashTool'
import { JsonTool } from '../tools/JsonTool'
import { UUIDTool } from '../tools/UUIDTool'
import { TimestampTool } from '../tools/TimestampTool'
import { ColorTool } from '../tools/ColorTool'

export class ToolBootstrap {
  static init(): void {
    ToolManager.register(new QRCodeTool())
    ToolManager.register(new Base64Tool())
    ToolManager.register(new HashTool())
    ToolManager.register(new JsonTool())
    ToolManager.register(new UUIDTool())
    ToolManager.register(new TimestampTool())
    ToolManager.register(new ColorTool())
  }
}

提示:扩展机制的关键在于"约定优于配置",只要新工具遵守 ToolBase 接口约定,就能无缝接入,无需改动既有代码,符合开闭原则。

总结

本文完整实现了 HarmonyExplorer 的效率工具箱,涵盖 ToolManager 插件化架构、ToolCard 组件、七大工具实现以及扩展机制。插件化架构让工具箱具备了良好的可扩展性,统一的 ToolBase 接口保证了工具开发的一致性。各工具实时计算的交互模式也大幅提升了使用效率。希望这套设计方案能帮助你在鸿蒙项目中构建可演进的工具箱体系。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!

相关资源

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐