资讯动态

用AI coding给旧智能手表写个番茄钟待办应用全攻略

发布时间:2026/10/22 5:41:38 来源:尧图企业网站定制
我承认最早让我起这个念头的纯粹是那块旧表一直吃灰太可惜。华米Amazfit GTR4本身运行的是Zepp OS这块系统虽然平时看着像“表盘通知中心”但它其实支持小程序开发JS写页面跑起独立的番茄钟和待办列表完全没问题。真正让我动起来的是现在的AI coding工具已经把“从零搭一个自定义手表小应用”的门槛降得很低了——我只需要把需求讲清楚、把官方文档喂给AI剩下的脚手架代码、页面UI布局、甚至不少API调用示例AI都能先给我铺出来。我踩完一轮坑之后发现整个过程完全可以整理成一篇文章写给那些手上有同款旧智能手表、又不太确定应该从哪里开始的人。这篇文章里我会按照我实际动手的顺序先说项目和Zepp OS的关系再讲AI coding在中间到底承担了什么角色接着把番茄钟和待办列表两块核心功能拆开讲最后列几个真机调试时最容易翻车的点。如果你也想给手头手表写点“只有自己能用”的小应用这篇文章应该能帮你少走不少弯路。1. 项目缘起为什么放着现成工具不用非要给旧表写个专用应用1.1 旧手表不是不能装应用只是默认生态里没有刚好合胃口的GTR4这表刚到手那阵我也像大多数人一样表盘换了一圈、消息提醒开满新鲜劲过了就觉得它跟手机上的联动还是太“大而全”。系统商店里的应用确实有一些但番茄钟类的应用往往只给一个倒计时页面待办列表要么单独在手机App里维护要么压根不支持本地保存。我想要的其实很简单抬起手腕就能看到一个正在走秒的番茄倒计时旁边捎带手能翻出今天最要紧的三件事而不是在通知流里扒拉着找。之所以没有选择去商店找一个现成应用还有个原因是我对数据有点洁癖。我并不想为了记录几个待办就得把数据同步到某个云端账户。手表本来就是个私人物品待办这种高度个人化的数据存本地才是最直接、最放心的方案。Zepp OS小程序恰好支持本地文件读写做个JSON格式的待办存储一点不复杂这就给了我一个挺舒服的落点。另一个很重要的现实因素是GTR4这样的圆表屏幕分辨率不算高交互也只能靠触摸和按键。很多手机上用得顺手的“富交互”逻辑放到手表上反而会变得臃肿。自己写的好处就是能把所有交互裁剪到刚好合适计时、暂停、继续、切换待办、打勾五个动作撑起整个应用。这是现成应用很难为我做定制的地方。1.2 我想要的“番茄待办”到底长什么样先说番茄钟部分。我长期用的是最简单的番茄规则25分钟专注5分钟短休完成4轮之后来一次15分钟长休。这个规则在手机上用App已经很多年了搬到手表上唯一要改的是不要给用户太多“参数设置”的机会。手表屏幕就那么大我不想为了改一个时长去翻三级菜单所以第一版我直接在代码里定义常量把25/5/15写死。再说待办部分。我需要的不是那种能建文件夹、加标签、设优先级提醒的全功能待办手表上根本看不过来。我需要的是今天有哪些事、按什么顺序做、做完哪件划掉哪件。所以数据结构也定得很简单就是一个数组每个元素有id、标题文本和完成状态。主页面下方用滚轮或者触摸滑动来切换待办点一下圆圈标记完成。最后是“番茄和待办怎么配合”。我这人经常遇到的情况是番茄钟已经开始跑了但做完一件事后突然不知道下一步该干嘛。所以我特地在番茄开始之前让应用停留在待办列表页并且高亮显示下一个该做的事。这样我在按下“开始专注”之前已经明确了当前要做的目标而不是等计时器滴滴响完了再去想去哪件事。1.3 平台限制和我的取舍Zepp OS的开发模型跟手机端不太一样并不是每个应用都能像手机App那样在后台自由运行。像计时这个功能最稳妥的方式是让应用在前台保持运行依赖页面的生命周期来处理计时状态如果用户切到别的表盘或者应用退出JavaScript上下文就不可靠了。为了不踩这个坑我做了个简单取舍番茄钟一旦开始手表会停留在应用页面通过画面的变化提醒用户别切走。数据存储方面Zepp OS提供了文件读写能力读写个小JSON完全够用。但我不打算为“实时多端同步”去折腾网络请求因为手表应用本来就不该依赖网络才能工作。真要换手机、换手表待办列表丢了也就丢了它本身就是给“当下”服务的。这个取舍很重要它让我能把整个开发量控制在一个周末以内。2. AI coding到底帮我省了多少事2.1 我让AI参与的工作范围如果你用过AI coding工具一定知道它最擅长的是“根据上下文生成样板代码”最不擅长的是“在没有约束时凭空给你一个高质量系统”。我这次给手表写应用就严格按这个原则分工。AI负责的第一块是项目脚手架。Zepp OS小应用虽然结构比手机工程简单但依然有页面文件、入口文件、配置文件、全局样式这些“硬框架”。这些框架代码人人写的都差不多让AI生成一遍我再对着官方示例检查一遍比自己从空目录折腾要快得多。AI负责的第二块是UI布局代码。手表屏幕尺寸固定、控件种类有限用ai生成的圆形表盘上摆放时间文本、按钮、列表项参数基本就是坐标和字号的问题。这类事情正好是AI的舒适区我只需要描述“左上角放日期中央放倒计时底部放待办列表”它就能给我一版可跑的代码。AI负责的第三块是常见API调用的示例。比如怎么读取本地文件、怎么写一个标准JSON、怎么在页面上注册一个点击事件。这种“怎么调用某个函数”的问答与其翻文档不如直接问AI再回到官方文档里核对一遍。我自己亲手写的部分主要集中在一个地方应用的核心状态管理。计时器什么时候暂停、什么时候重置、待办做完之后要不要自动跳到下一项这些跟产品逻辑强耦合的代码AI给出初版后我必须一行行自己审。毕竟它不知道我在抬手看表的那一秒里真正在意的是什么。缩略下来AI帮我省下的时间主要是在“把想法变成代码草稿”这一块而节省下来的精力我都花在了更重要的逻辑验证和真机调试上。2.2 把Zepp OS的API讲给AI听这里有个经验值得单独拿出来说AI coding如果给不出好答案往往不是AI不行而是你没给它足够好的上下文。Zepp OS的API跟通用Web API有挺明显的区别。比如页面上显示文本它有自己的createWidget体系样式的配置方式是对象参数里的color、text_size、align_h这些字段跟CSS完全两码事。你要是不告诉AI这些背景它就很有可能会给你生成一段在手机上能跑、在手表的JS引擎里完全不认识的代码。我当时的做法是先把官方开发文档里几个核心页面的内容复制出来粘到AI对话框里作为“虚拟开发手册”然后明确告诉它这是Zepp OS的手表应用应用目标屏幕是466x466不能使用DOM和CSS语法UI必须用createWidget创建。有了这一层约束AI后续生成的东西基本不会跑偏。还有一个被我反复使用的技巧让AI尽量返回“可运行的完整片段”不只是零散的函数。因为手表应用的页面生命周期和文件依赖关系只有完整代码块才能体现出来。比如我要它输出一个“倒计时文本组件”我会要求它带上页面初始化的上下文这样我能直接复制到工程里跑而不是再自己脑补怎么接入生命周期。2.3 AI会翻车的地方有哪些AI生成的代码里最典型的问题是对“模块导入路径”不敏感。Zepp OS的SDK导入是类似zos/ui、zos/fs这样的别名但AI有时候会给你来一个玄乎的绝对路径这种代码一编译就报错。解决方法是建立一份自己的“常用导入清单”凡是AI生成的代码先检查顶部的import部分不对就直接改掉。第二个容易翻车的地方是生命周期概念。AI很习惯用“页面打开时启动计时器”这种直觉逻辑但手表应用切后台再切回来界面刷新跟计时器并不同步。AI不会主动为你考虑“用户正在看别的页面回来时倒计时应该显示正确时间”这种状态恢复问题我得自己加上时间戳校验的逻辑。第三AI生成按钮的回调函数偶尔会带上浏览器风格的对象参数比如event.preventDefault()这种这在手表环境里完全不存在。我的经验是每批代码生成之后先跑一遍静态检查再对每个交互回调做一次“环境合规审”重点就是看有没有混入网页端习惯写法。3. 番茄钟和待办核心代码怎么落到手表上3.1 计时器循环与页面UI的同步手表上的番茄钟跟我平时在手机上见到的实现方式有一个很大的不同手机App可以在后台继续跑计时手表上的小程序则更依赖页面保持在前台状态。所以我也不做什么复杂的设计就是最朴素的倒计时循环。核心思路是保存一个“目标完成时间戳”然后用setInterval每秒触发一次刷新把剩余秒数转成MM:SS格式显示在页面上。为什么不用每秒减去一个变量因为一旦中间有任何卡顿或者页面被短暂覆盖减法的累计误差就会越来越明显。而用时间戳计算无论页面什么时候刷新拿当前时间去减目标时间得到的剩余秒数永远是正确的。具体代码的逻辑里一个比较关键的点是页面生命周期回调。我在onInit阶段读取初始时间戳和当前待办数据在onDestroy阶段把计时器状态写入本地文件。这样就算番茄钟还没有结束用户只是暂时退出应用下次打开时我也可以恢复出“已经跑了10分钟”的状态而不是傻乎乎地清零重来。界面显示上我让AI帮我把倒计时文本做成了整页居中大字。手表和手机不一样你不会举着它凑近了看字号不够大就意味着完全不可用。GTR4的屏幕分辨率还算不错我用了接近屏幕宽度一半的字号来显示分钟部分其余部分只保留最小限度的装饰性信息。你可能会关心震动提醒。Zepp OS提供震动相关的能力但并不是说调用震动接口就一定能震它在某些模拟器环境里是不响的。所以我写到后期干脆把“震动测试”这件事放到真机上验证而不是在模拟器阶段纠结。3.2 待办清单的文件存储与数据格式待办数据我选择了最直接的JSON文件方案。每一条待办就三个字段id、text、done。id用当前时间戳加随机数生成text是用户输入的标题内容done是一个布尔值。这里要特别说一个设计我没有给待办做“编辑”和“删除”功能只做“完成”。确切点说我允许用户长按某一条待办把它标记为删除但日常交互的主按钮永远只有一个——完成。因为手表上输入文本已经够笨重了如果再塞一个编辑流程这应用基本上就变成了一场灾难。第一版我本来还考虑过做“上下左右”排序功能后来还是决定砍掉因为那个功能的使用频率远低于它的调试成本。存储模块我用的是一个简单的“读取全部-修改-写回全部”模式。这个逻辑说实话不太优雅但如果待办总数不超过十条性能上毫无问题而且代码逻辑非常容易被AI生成、被我自己审查。真要做一个同时支持几百条待办的存储方案那就不太适合放在手表应用里了。验证存储是否成功我喜欢用一句日志来观察。在本地写入之后紧接着读一遍文件把内容和当前内存里的数组做一个比对。这个习惯帮我提前抓到了好几个“数组对象没有深拷贝”的隐患因为JS里如果直接用对象引用去序列化很容易造成修改一个地方、所有地方都变了的错觉。3.3 一轮完整的操作流程套完整的流程我描述给你看看早上到工位先点亮手表打开我写的这个番茄待办应用。应用启动后会把本地存储的待办列表读出来默认高亮第一个未完成的任务。我在列表页面左滑右滑检查今天要做什么然后按一下表冠进入番茄钟页面倒计时25分钟开始。专注过程中我可能会抬手看几眼时间半途如果来了个电话手表画面会自然跳到来电界面。处理完电话再回来时应用还在因为计时器的基准是那个目标完成时间戳所以显示出来的剩余时间分毫不差。25分钟结束震动提示加界面翻转成休息倒计时我再按一下确认进入5分钟短休。这一整套流程的核心设计原则是“少敲”。手表上的任何输入都要付出比手机上高得多的代价所以能做进流程里的交互就不要让用户做。我甚至把“番茄结束之后要不要自动开始休息”默认成了“自动倒计时但需要手动确认”既不会错过休息也不会稀里糊涂又进入一个专注周期。4. 真实设备上的六个坑与排查方法4.1 开发期没有真机可以做多少事刚开始写这个项目的时候我没有天天把手表连在电脑上而是在Zepp OS官方提供的模拟器里反复试。模拟器能做很多事显示UI布局、模拟触摸事件、校验API调用不会报错甚至能让你看到应用启动时的大致效果。对于我这种主要写页面逻辑的人来说前80%的代码都可以在模拟器里写完。但要敲黑板的是模拟器跟真机的差距依然不小。最明显的差异有三个真机的屏幕边缘有金属边框和圆角裁切模拟器预览时不那么明显真机的触摸手势跟鼠标点击的判定条件不同滑动误触的概率会高一些还有一个是在模拟器里测试震动和某些健康传感器的反馈基本等于没有。所以我给自己定了个规矩所有涉及“物理反馈”和“手势细节”的内容必须最早安排真机测试。真机安装本身并不复杂。编译工程之后会得到一个小应用的安装包手腕上的设备可以通过官方工具把它推到表上。如果你是第一次接触这个流程优先找官方的开发者文档里面会告诉你手机App和手表建立调试连接的步骤。我当时第一次安装也卡了小半天因为总以为是电脑和手表直连实际上很多时候是先让手表和手机配对再通过手机中转安装。4.2 需要记录在案的Bug与修复方案我把我踩过的坑整理成一张表每一行都是实际出现过的问题不是纯理论猜测。问题现象实际原因解决方式倒计时显示时间比真实时间慢模拟器里的setInterval受渲染帧率影响不稳定真机上验证改用时间戳差值计算不依赖每秒累加中文待办在模拟器显示乱码文件编码和页面默认编码不一致确认工程用UTF-8保存避免使用带BOM的编辑环境震动提醒偶尔不触发接口调用在应用不活跃时失效改成页面保持前台时触发并做真机调试确认基线待办条目数量多了之后滑动手感变卡每次滑动都重建整个列表组件只刷新当前可见区列表的单项变成独立组件从待办页切到番茄页再回来高亮位置丢失页面销毁后没有保存滚动位置在onDestroy时写一个当前索引到文件启动时恢复手表灭屏后回来应用显示的“剩余时间”不变页面没有跟系统时间戳重新对齐每次生命周期恢复时重新读取当前时间和目标时间戳这些bug里最让我印象深刻的是“时间变慢”那个。其实模拟器里跑得很正常但在真机上隔了三个小时再打开应用发现显示时间还停留在“刚开始专注”的状态。我后来细查了一下发现是因为模拟器在“非页面后台”状态下根本没有运行计时相关的代码。改成时间戳方案后无论系统什么时候恢复应用都能立刻算出正确的剩余分钟数这个问题就从根上消失了。还有一个经验值得写在这里真机上做页面切换测试的时候不要只测正常流程。我后来故意在计时中途切表盘、在待办页面直接息屏、在应用刚启动时疯狂点击按钮这些“没素质操作”才真正暴露了状态恢复的脆弱点。很多手表应用看着不错一旦放到日常混乱的使用场景里就露馅就是因为开发者没这么折磨过自己的代码。4.3 也有些让你想砸表的“环境项”除了代码本身的bug还有一类问题纯粹来自开发环境本身。比如我在某个版本里发现官方模拟器对“多行文本”的渲染支持不完整导致我在模拟器里怎么调字号真机上都是一坨重叠的字符。这种问题排查起来特别折腾因为它不是我的逻辑出错而是工具链的边界。我的解决办法比较土把所有多行显示改成单行文本加截断宁可少显示几个字也不要出现排版错乱。另一个环境问题是编译产生的警告信息。Zepp OS的编译链并不总是像常规前端那样很直白地告诉你“这里出错了”有时候只是一个warning但是在真机上运行时直接白屏。我后来把警告全部当成错误来处理一旦看到warning就先停手排查避免把隐患一路带到真机测试阶段。如果你计划给手表开发更复杂的功能建议你在动手之前就把真机和模拟器的双环境测试考虑进去。不要等到最后一刻再切换因为适配问题永远是“越早发现越便宜”。5. 落地后的使用体验和后续扩展5.1 这款手写番茄应用在真实场景里的状态应用写完之后我连着用了两周。实话实说戴着手表开25分钟番茄的体验跟手机完全不同手机上的番茄钟App我经常静音放一边过五分钟就忘了手表抬腕即见的倒计时反而让我更专注因为它就贴在手腕上不用额外去拿手机解锁。待办列表的使用频率比我预想的还要高。以前在手机上记完待办锁屏之后就等于不存在了手表上的待办则是抬手就能看到放在“下一步该做什么”的位置上。哪怕是临时想起来要回一封邮件、下楼拿个快递我都能第一时间打开手表补充进去这种随手性是很强的动力。不过也要坦白说这个应用不完美。受限于手表输入待办的标题都必须尽量短超过四五个词之后就很难完整显示。而且我并没有做手机端的同步入口待办只能在手表上补充所以它更适合记录“短时记忆”没法承担复杂的项目管理职责。5.2 如果继续做我会优先加什么如果后续要更新我第一个想加的是“语音转文字添加待办”。手机上的语音输入已经很成熟了但手表的本地模型不一定能胜任更大的可能还是借助手机联动实现。这需要手表跟手机之间做一层通信工程复杂度会比我当前这一版大不少但做出来之后输入的痛点算是能真正被解决。第二想加的是“番茄统计数据”。我已经把每次专注的开始时间和是否完成记在本地文件里了但还没有做汇总分析。后续可以在手表上做一个简单的“今日专注次数”展示或者在配套手机上做一个小页面每周看看自己到底专注了多久。这不需要太多新代码只要在原来的存储基础上再加一个统计维度就行。第三个想法是把表冠的旋转利用起来。GTR4的表冠可以旋转系统也支持相关事件。我现在只用它做“模向切换页面”后续可以考虑用旋转来调整番茄的时长比如轻松转动一下从25分钟调成当前的剩余时间这样比点按钮更顺滑。5.3 最后给想动手的人的一点建议如果你现在手头也有一块带Zepp OS的旧手表想试试自己写个能用的小应用我建议你第一版一定要定个特别小的目标。别一上来就想着搞什么语音助手、多端同步、复杂动画先把一个番茄钟或者一个待办列表跑通安装到手上用两天你才能真正理解手表应用和手机应用的差异在哪。这个理解远比功能多少重要。AI coding在你动手时能当很好的帮手但它更像个干活麻利但不太懂你心思的合作者。你给它喂的资料越完整它返工次数就越少你在现场能看懂它的代码、能上手修它才能在后续迭代里帮上更重要的忙。不要变成那种“AI写代码、我也看不懂、坏了就重开”的开发方式那在手表这个小屏环境里会让你非常难受。最后再说个实用的小技巧手表应用跟手机App最不一样的地方是它的“主要入口”并不总是靠点击而来的很多时候是抬腕亮屏、瞥一眼再放下。所以你在设计任何界面的时候都先问自己一句话——在0.5秒钟的扫视里用户能不能一眼看到他最需要的信息。这句话我每次写UI都会默念一遍。它为我的这个番茄待办应用带来了一种手机上很难体验到的爽感也让那块本来吃灰的手表重新变成了带在手上的“今天要做的事”。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑