HarmonyOS组件-模拟时钟组件

0 阅读6分钟

给 HarmonyOS NEXT 应用加一块“会呼吸”的模拟时钟

在做 HarmonyOS NEXT 应用的时候,你可能也有过这种念头:

“这里放一个模拟时钟应该挺好看……不过要自己画盘、写动画、适配各种尺寸,还得处理时间更新,算了,下次再说。”

结果,这个“下次”就真的一直没来。
所以干脆把这件事替你做了:做了一个开箱即用的模拟时钟组件库 analog_clock

它已经在 HarmonyOS NEXT 上跑通,支持亮色 / 暗色双主题、自适应布局、流畅指针动画,直接引入就能用,基本不用操心细节。

下面简单介绍下它能做什么、怎么用,以及为什么值得集成进你的项目。


组件能做什么?

1. 真的“在走”的模拟时钟

  • 基于 ArkTS 动画能力实现,时针、分针、秒针实时走动,每秒刷新。
  • 指针角度采用增量计算,专门处理诸如 59 秒 -> 0 秒 这类跨周期场景,避免出现突然“倒转一大圈”的违和动画。
  • 动画使用线性曲线,视觉效果自然流畅,看着就是一个“正常的时钟”。

2. 自适应任何容器尺寸

  • 组件内部通过 onAreaChange 监听区域变化,自动计算一个合适的 clockSize
  • 无论你给的是固定高度、百分比宽度,还是使用 layoutWeight 分配空间,时钟都会自动保持正圆比例,不会被拉伸、压扁。
  • 简单讲:只要给它个地方,它自己会“长成一个漂亮的圆”。

3. 亮色 / 暗色双主题

组件内置两个实现:

  • AnalogClockLight:亮色主题,适合白天、浅色背景、卡片式 UI。
  • AnalogClockDark:暗色主题,更适合深色背景、夜间模式。

你可以在不同页面、不同区域自由组合使用,也可以配合系统主题切换来决定选择哪个组件。

4. 自动运行 + 安全收尾

  • 组件在 aboutToAppear 时自动:
    • 获取当前系统时间;
    • 启动定时器,每秒更新一次指针角度。
  • aboutToDisappear 时自动:
    • 清理定时器;
    • 释放资源,避免内存泄漏。

你无需自己管理计时逻辑,组件在生命周期内会自顾自地“负责到底”。


如何集成到你的项目?

安装依赖

在DevEco Studio中点击Tools->Component Market:

在搜索框输入“模拟时钟”查询:

点击组件旁边的安装按钮即可集成到你的项目中使用了,非常方便~~

或者你也可以在工程根目录执行:

ohpm install analog_clock

安装完成后,在需要使用的页面引入组件:

import { AnalogClockLight, AnalogClockDark } from 'analog_clock';

最基础的用法

组件默认会根据父容器大小自适应,下面是一个最常见的布局示例:

@Entry
@Component
struct Index {
  build() {
    Column({ space: 20 }) {
      // 亮色时钟
      AnalogClockLight()
        .width('100%')
        .height(200)

      // 暗色时钟
      AnalogClockDark()
        .width('100%')
        .height(200)
    }
    .padding(20)
  }
}

你只需要决定给它多大的区域(比如 200 高度),时钟本身的圆形和指针比例都会自动搞定。

在自适应布局里使用

如果你喜欢用 layoutWeight 做“卡片 + 内容”布局,可以这样玩:

Column() {
  // 上面可以是一些标题、描述等
  Text('Today')
    .fontSize(20)
    .margin({ bottom: 10 })

  // 时钟自动填充剩余空间
  AnalogClockLight()
    .layoutWeight(1)
    .width('100%')
}
.height('50%')

这里 AnalogClockLight 会自动占满剩余高度,内部再根据宽高取短边,保证始终是一个完整的圆形表盘。

亮 / 暗双卡片示例(类似演示应用)

比如你想在首页放两个卡片,分别展示 Light / Dark 模式,大致结构可以是:

import { AnalogClockDark, AnalogClockLight } from 'analog_clock';

@Entry
@Component
struct Index {
  build() {
    Column({ space: 20 }) {
      Text('HarmonyOS 模拟时钟')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 40, bottom: 10 })

      // Light 卡片
      Column() {
        Row() {
          Text('Light Mode')
          Blank()
          Text('白天')
        }
        .width('100%')
        .margin({ bottom: 15 })

        AnalogClockLight()
          .layoutWeight(1)
          .width('100%')
      }
      .width('90%')
      .layoutWeight(1)
      .borderRadius(24)
      .padding(20)

      // Dark 卡片
      Column() {
        Row() {
          Text('Dark Mode')
          Blank()
          Text('夜间')
        }
        .width('100%')
        .margin({ bottom: 15 })

        AnalogClockDark()
          .layoutWeight(1)
          .width('100%')
      }
      .width('90%')
      .layoutWeight(1)
      .backgroundColor(Color.Black)
      .borderRadius(24)
      .padding(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Center)
  }
}

这类卡片式 UI,在演示应用里已经有现成的效果,可以直接参考或照抄结构稍微改改样式。


为什么值得集成这个组件?

1. 少踩一堆小坑

自己写一个看起来“简单”的模拟时钟,实际要面对的问题包括:

  • 指针角度的计算和跨周期动画的平滑;
  • 表盘 / 指针资源的适配;
  • 不同尺寸设备上的自适应展示;
  • 定时器的创建和销毁,防止内存泄漏;
  • 卡片点击、跳转等交互扩展。

这些在 analog_clock 里已经处理过一轮,开发者可以直接站在一个稳定版本的基础上,而不是从零开始踩坑。

2. 节省时间,把精力放在“真正有差异化”的地方

一个模拟时钟本质上是“装饰 + 信息展示”。
它会让界面更有“生活气息”,但并不是你应用的业务核心。

与其花几天时间从头写一个模拟时钟,不如:

  • 花几分钟装一个现成的;
  • 把时间用在真正能拉开差距的业务和体验上。

对一个要频繁迭代的项目来说,你能少维护一块公共组件,就少一块长期的“心智负担”。

3. 轻量、纯 ArkTS/ArkUI、无复杂依赖

  • 组件是基于 ArkTS/ArkUI 实现的,不引入额外第三方重依赖
  • 以 HAR 包的形式提供,结构清晰,并已完成正式签名,方便集成与分发;
  • 对于需要上架或多项目复用的团队来说,这种形态更容易管理。

适合哪些场景?

简单列几个典型场景作为参考:

  • 桌面 / 仪表盘类应用:顶部一个模拟时钟,下面是各类状态信息;
  • 教育 / 亲子应用:教小朋友认时间,比数字时钟更有趣,也更贴近生活;
  • 时区 / 世界时间应用:多个不同主题的时钟同时展示,不同城市不同风格;
  • 主题类 App 或个性化界面:配合你的整体 UI 设计,让时钟变成界面的一部分“装饰物”。

只要你有一个“这里放个时钟应该不错”的地方,基本都可以用这个组件快速填上去。


最后,小小的呼吁

如果你正在做 HarmonyOS NEXT 的应用,有这些需求:

  • 想要一个好看、顺滑、能自适应的模拟时钟
  • 不想再为角度、动画、适配这些细节花时间;
  • 希望组件足够轻量、易集成,还能放心放到正式项目里;

那非常欢迎你直接在项目里集成 analog_clock

引入后两行代码就能把时钟放到页面上,用起来非常“省心”。

如果你在使用过程中有任何想法(比如需要更多主题、可定制表盘、增加数字刻度样式等),也非常欢迎在开源仓库 (gitcode.com/qiaomu85599…) 里提 Issue 或者留言交流。
希望这个小组件,能真正在你的项目里帮你省下一点时间,让你的界面多一点“生活感”。