需求背景:下午三点的「脑子被抽空」

上个月连续赶了两周需求,某天下午三点坐在工位上,盯着屏幕发现自己一个字都写不出来。不是不想写,是脑子像被抽空了。打开手机看了眼电量——37%,我心想:我自己大概也就剩这么多了。

这个念头一冒出来就挥之不去。我们对「百分比在掉」这件事有天然的紧迫感,如果把自己的精力也做成一块电池呢?充了什么、耗了什么、还剩多少,一目了然。于是我做了「元气手账」,一个精力收支记录工具。iOS 版用 SwiftUI 写的,最近我又着手把它迁移到 HarmonyOS 生态,用 ArkUI 重新实现了一遍核心交互,这篇文章聊聊整个过程的设计思路和技术实现。

核心逻辑:一块虚拟电池的加减账本

产品逻辑很简单:每天你有一块虚拟电池,满电 100%。做了让你恢复精力的事(午睡、散步、和朋友聊天),加电;遇到消耗精力的事(无效会议、争吵、连续写代码三小时没休息),减电。实时看到当前余额。

不需要写长篇日记,也不需要给情绪打 1-10 分。我预设了几十个常见场景胶囊,比如「深度工作 90min」「刷短视频 30min」「被甲方改需求」,点一下就记上了,整个过程不超过 5 秒。

跑了一周数据之后,App 会自动帮你找出两类东西:吸血鬼(持续让你掉电最猛的事)和绿洲(充电效率最高的事)。我自己跑出来的结果挺意外的——以为刷 B 站是休息,实际上它是个轻度耗电项;反而是出门买杯咖啡走一圈这种小事,充电效率极高。

技术实现:从 SwiftUI 到 ArkUI 的迁移思考

iOS 版最低支持 iOS 17,数据层用了 SwiftData,不依赖任何后端。选 SwiftData 而不是 Core Data 主要是因为模型定义太舒服了,配合 @Query 做列表刷新几乎不用写额外代码。

电池余额的核心计算本质上就是一个 reduce,iOS 端的实现长这样:

func currentBalance(for date: Date) -> Int {
    let logs = fetchLogs(for: date)
        let balance = logs.reduce(100) { current, log in
                switch log.type {
                        case .charge:
                                    return min(100, current + log.value)
                                            case .drain:
                                                        return max(0, current - log.value)
                                                                }
                                                                    }
                                                                        return balance
                                                                        }
                                                                        ```
没什么花哨的算法,但这种「加减账本」的心智模型比让用户纠结「我今天到底是 6 分还是 7 分」好懂太多了。迁移到 HarmonyOS 时,这部分逻辑用 ArkTS 重写非常直接,数据持久化我选了关系型数据库 relationalStore,配合 HarmonyOSDataAbility 做本地存储,体验上和 SwiftData 的声明式风格各有优劣,但胜在跨设备同步的扩展性更好。

电池动画是我花时间最多的部分。iOS 端用的是 `TimelineView` 配合 `Canvas`,帧率控制在 30fps,实测在 iPhone 12 mini 上功耗可以忽略不计。本来想用 Metal 写 shader 做液体效果,后来觉得杀鸡用牛刀,改成了渐变色块 + 圆角 mask,视觉上差不多但代码量少了 80%。在 ArkUI 这边,我用 `Canvas` 组件配合 `@State` 驱动重绘,思路类似:

```arkts
@Entry
@Component
struct BatteryView {
  @State balance: number = 100
  build() {
      Column() {
            Canvas(this.bindCanvasContext)
                    .width('80%')
                            .height(200)
                                    .onReady(() => {
                                              this.bindCanvasContext.bindbindbindRectBindings
                                                        let ctx = this.bindCanvasContext
                                                                  let fillHeight = 200 * (this.balance / 100)
                                                                            ctx.fillStyle = '#34C759'
                                                                                      ctx.fillRect(0, 200 - fillHeight, 280, fillHeight)
                                                                                              })
                                                                                                    Text(`${this.balance}%`)
                                                                                                            .fontSize(48)
                                                                                                                    .fontWeight(FontWeight.Bold)
                                                                                                                        }
                                                                                                                          }
                                                                                                                          }
                                                                                                                          ```
ArkUI 的声明式语法写动画组件还是很顺手的,和 SwiftUI 的心智模型接近,迁移成本比我预想的低。

## 和其他工具的定位差异

用过 BearableDaylio、小日常这些。Bearable 功能强但太重了,每次记录要选半天维度;Daylio 本质是情绪日记,不是精力管理;小日常是习惯打卡,关注的是「做没做」而不是「做了之后你是充电还是掉电」。

元气手账只关心一件事:你的精力收支。这个定位窄,但我觉得对考研党和高强度码代码的人来说反而够用。你不需要一个大而全的生活管理系统,你需要的是快速知道自己还剩多少电、以及什么东西在偷偷吸你的电。

## 目前状态和后续计划

iOS 版已经上架 App Store,搜「元气手账」就能找到。免费下载,核心功能不收费,吸血鬼/绿洲洞察是订阅解锁的(我得恰饭)。HarmonyOS 版还在开发中,计划适配鸿蒙的卡片服务,让用户在桌面就能看到当前电量和一键记录,这个场景和 HarmonyOS 的服务卡片能力天然契合。

如果你也经常在下午三点感觉自己被掏空,可以先试试 iOS 版记一周看看。不一定要长期用,哪怕只是跑一周数据看看自己的吸血鬼 TOP3 是什么,也挺有意思的。

如果你也在做鸿蒙开发,或者对 SwiftUIArkUI 的迁移有经验想交流,欢迎评论区聊,技术实现或者产品设计都行。

Logo

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

更多推荐