给 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 或者留言交流。
希望这个小组件,能真正在你的项目里帮你省下一点时间,让你的界面多一点“生活感”。