HIT-快应用 | 我想做一个简单的待办清单,结果把状态机、Canvas 和语音输入都招来了

HIT-Quick-App-TODO

一开始做这个快应用时,我给自己定的目标非常克制:做一个能记待办事项的小工具。能新建,能编辑,能删除,最好还能把“正在做”和“已经完成”分开。听起来不像一个会把人折腾很久的项目。

结果写着写着,事情开始变多。一个待办事项要有状态,要有截止时间,要能保存;统计页要画图;输入框最好能接语音;完成操作以后还想给一点震动和 Toast 反馈。最后这个项目已经不只是一个清单,而变成了一次小型应用开发实验。

仓库地址:KALEsky/HIT-Quick-App-TODO。它使用较早的快应用/HAP 工具链,记录的是当时对移动端状态管理、平台能力和 Canvas 绘图的一次尝试。

先从最普通的待办事项开始

项目最初的页面很直白:输入事项,选择截止时间,然后把它放进列表。可只要真的开始操作,就会发现“一个事项”并不是一行文字。

它至少需要有内容、开始时间、截止时间和当前状态。状态又分成 TODODOINGDONE。如果没有截止时间,还要有一个 NO DDL 的分支。用户点一下完成,事项应该从进行中的列表移动到完成列表;重新编辑以后,统计页也要同步变化。

我一开始很容易把这些变化直接写在页面点击事件里:点这里改一个数组,点那里再改另一个数组。功能少的时候还能勉强维持,操作一多就开始出现状态不同步。页面显示完成了,存储里的数据却没变;重新打开以后,刚才的修改又消失了。

后来我把这部分看成一个很小的状态机:

动作状态变化需要同步的地方
新建事项 无 → TODO 列表、持久化存储
开始处理 TODO → DOING 当前列表、统计数据
完成事项 DOING → DONE 完成列表、状态曲线
重新打开 DONE → DOING 页面、存储、统计图

这张表不复杂,却帮我把很多页面逻辑重新理顺了。状态变化不是某个按钮的私事,它会影响整个应用里和这条数据有关的部分。

本地存储:退出页面以后,事情不能凭空消失

如果待办事项只存在内存里,页面一刷新就全部归零,这个工具就没有什么实际价值。项目使用 @system.storage 保存三类列表,让用户退出页面以后重新回来,还能看到之前的事项。

这一步让我第一次认真面对“数据什么时候写入”的问题。是每次输入一个字符就保存,还是用户点击确定以后再保存?编辑中途退出怎么办?完成一件事以后,是先刷新界面再保存,还是先保存成功再更新页面?

课程项目里没有完整的数据库,也没有登录和云同步,所以它的边界非常清楚:这是一个本机待办工具,不是跨设备的生产级任务系统。但正因为范围小,我反而能更清楚地看到持久化给界面带来的影响。

统计页:我只是想画两张图,结果开始处理边界条件

统计页是这个项目里最有趣、也最容易暴露问题的地方。它用 Canvas 画两张图:一张展示 TODO、DOING、DONE 三种状态的数量变化,另一张按截止时间分成超时、一天内、一周内、一月内和更远的事项。

一开始我以为画图就是把数字换成坐标,再连几条线。真正写起来以后,坐标系统、最大值最小值、标签位置和数据为空的情况都会找上门。尤其是三种状态数量完全相同时,最大值和最小值的差变成 0,归一化计算就可能出问题。

这个小 bug 很有代表性。它不是算法不会写,而是我只考虑了“正常数据”,没有考虑“所有数据刚好一样”的情况。后来给比例计算加保护以后,图才不会在某些状态下突然塌成一条线。

截止时间环图也让我意识到,日期处理不是把字符串拼起来那么简单。月份补零、时区、跨天和没有截止时间,都会让“还有几天”这句话变得不可靠。项目里仍然保留着当时的简化实现,这也是它作为历史实验的真实部分。

语音输入、震动和快捷方式:平台能力接进来以后,产品感突然出现了

为了让这个待办工具不像一个纯表单页面,项目还接入了 @service.asr 做语音输入。用户可以通过语音快速录入事项,操作完成以后再用短震动和 Toast 给出反馈,还尝试从菜单创建桌面快捷方式。

这些功能本身不算复杂,却让我第一次感觉到,应用开发和写一个算法程序的关注点不完全一样。算法只要输入输出正确,很多时候就已经完成了;应用还要在意操作是否有反馈、页面是否及时更新、用户是否知道刚才的动作有没有成功。

当然,平台能力也带来了依赖。语音识别、震动和快捷方式都和具体设备、权限以及加载器有关。在模拟环境里能看到界面,不代表换一台设备就能完全复现。

工具链和那些不太体面的旧代码

项目使用的是比较早的 HAP Toolkit 和 Node.js 生态,命令包括 npm run startnpm run watchnpm run buildnpm run releasenpm run lint。现在回头看,依赖版本、平台 API 和资源文件都带着明显的年代感,现代环境大概率需要重新适配。

我没有为了让它看起来像新项目而把整个工程重写。旧的页面组织方式、日期处理和部分数据更新逻辑都保留在仓库里,因为我更想记录当时是怎样把功能拼起来的,而不是事后把它改造成一个看不出历史痕迹的样板工程。

这次小项目给我的最大收获,不是 Canvas

如果只看功能,这就是一个待办清单:三种状态、几个图表、语音输入和本地保存。但真正做下来,我反复遇到的都是同一个问题——一个用户动作发生以后,应用里到底哪些东西应该跟着变化。

新建事项会影响列表和存储;完成事项会影响状态和统计图;修改截止日期会影响分类;刷新页面又会检验之前的数据有没有真正保存。只要有一条链断掉,用户就会觉得应用“偶尔不对劲”。

这让我开始把页面想成一个小型系统,而不是一堆按钮。数据模型、状态转移、持久化、反馈和可视化,其实是一起工作的。哪怕项目规模不大,也需要有一条清楚的数据流。

现在我再看这个仓库,仍然能看到不少可以改进的地方:日期应该抽成可靠的时间模型,统计计算应该和页面解耦,三个状态相同的边界情况可以写成测试,语音和设备能力也应该有更明确的降级方案。

但它已经完成了当时最重要的任务:让我第一次从“写一个页面”走到“设计一个可以持续使用的小应用”。

仓库地址:HIT-Quick-App-TODO

说明:本文根据个人历史课程项目和公开仓库整理,部分文字经过 AI 辅助润色;项目依赖旧版快应用工具链,部分功能需要特定设备或加载器支持。课程资料仅用于学习回顾和个人作品整理,不用于当前课程作业或考试。

posted @ 2026-09-10 21:56  何以牵尘  阅读(5)  评论(0)    收藏  举报