乐于分享
好东西不私藏

两周,一个AI试衣APP,和那些"再改一下"的夜晚

两周,一个AI试衣APP,和那些"再改一下"的夜晚

两周,一个AI试衣APP,和那些“再改一下”的夜晚

事情要从两周前说起。

那天打开电脑,桌面上多了一个项目文件夹:virtual-tryon。需求很明确——做一个AI虚拟试衣APP,用户建个数字分身,拍几张衣服照片,AI生成穿在身上的效果。听起来就那么几件事:拍照、选衣服、点生成。

真做起来,才发现“就那么几件事”的背后,藏着无数个深夜的“这个再改一下”。

第一天到第三天:两天搭完框架,然后改了一周

Flutter 框架起得很快。两天时间,五个底栏 tab 就出来了——日历、衣橱、试衣、建议、我的。Provider 状态管理挂上,数据模型写好,JSON 序列化搞定,Demo 数据塞进去。跑起来,看起来像个 APP 了。

当时还挺满意。然后就给用户看了第一版。

反馈来得很快,也很直接——

“配色太单一了,就一个粉色。女性用户怎么可能都喜欢粉色?”

第四天到第六天:四套主题,一套都不能少

于是开始做配色系统。

公主粉、御姐红、清新蓝、阳光绿——四个主题,全局切换。听起来就是把 primary颜色换一下对吧?

不是。

每个页面里,背景色、卡片色、文字色、渐变、按钮、进度条、阴影——全都要根据当前主题动态计算。Colors.white不能写死,Color(0xFFF0F0F0)不能写死,所有地方都要改成c.backgroundc.surfacec.textPrimary

最坑的是constDart 里 const是编译时常量,但主题色是运行时才能确定的。于是满屏报错——“Not a constant expression”。光删 const关键字就删了两百多处,删完还要确认有没有破坏布局性能。

改了整整两天。每一个页面都重新打开、确认、编译、再改。

四套主题搞定后,以为可以松口气了。

然后用户说:“建议页的试穿效果点了没反应。”

第七天到第九天:一个按钮引发的跨页联动

打开代码一看,确实。

“试穿效果”按钮的 onPressed是这样写的:

void _tryOnOutfit() { showSnackBar('已选中3件衣物,请切换到试衣页'); }

就弹了一个提示,让用户自己手动切 tab。那搭配的衣物呢?没传过去。选了什么分身呢?也没传。

用户的感觉就是:点了,什么都没有发生。

这叫什么事?AI 给推荐了一套搭配——白衬衫、黑色阔腿裤、尖头高跟鞋、驼色风衣——点击“试穿效果”,啪,弹一句“请自己去试衣页操作”?

这不是功能,这是敷衍。

于是开始做跨页联动。思路其实不复杂:

1.  AppState 里加一个“待预选列表”,存着从建议页传过来的衣物ID

2. 加一个“待跳转 tab 索引”,让主框架自动切到试衣页

3. 试衣页读到预选列表后,自动勾选对应衣物和分身

但实现起来,四个文件要联动改动。models.dart加状态和方法,main.dart加监听器,advice.dart改造按钮逻辑,tryon.dart加自动预选逻辑。任何一个文件的逻辑出问题,整个流程就走不通。

最难调的是状态消费时机。预选数据读一次就要清空,否则下次进入试衣页又自动选中了上次的衣服。但如果页面还没渲染完就清空了,就会丢失数据。

反复改了好几次。最后加了一个_appliedPending标志位来控制,在build()方法里调用,只执行一次。

编译通过的那一刻,点了“试穿效果”→ 自动跳到试衣页 → 三件衣物整整齐齐勾选好。终于有“智能”的感觉了。


第十天到现在:会员套餐、关于页,和那些永远改不完的细节

跨页联动搞完之后,又发现了两个问题。

第一个是会员页。点“我的”页面顶部的“升级”按钮,弹出一个套餐列表——轻量版 ¥38/月、畅享版 ¥60/月、专业版 ¥99/月——看起来挺像那么回事。但仔细一看,每个卡片只展示了特性和价格,没有一个按钮可以真正订阅

纯展示。点了卡片啥反应都没有。

补上“立即订阅”按钮后,顺便把“关于”页里的“开发框架:Flutter + FastAPI”删了——用户说这种技术细节不要暴露给最终用户。

这种细节改动,说大不大,说小不小。但一个产品是 Demo 还是能用的东西,区别就在这儿。

一些感受

两周时间,一个看起来不算复杂的APP。

搭框架两天。然后打磨、修改、再修改——又花了一周多。

最大的体会是:做一个能用的东西很快,做一个好用的东西需要耐心。

代码写得再优雅,架构再合理,用户看到的永远是表面的那层——这个按钮有没有反应、点了会不会跳转、颜色看起来舒不舒服。那层东西,没有捷径,就是一遍遍试、一遍遍改。

还有一个体会:状态管理是Flutter里最容易出问题的地方。 Provider很好用,但一旦涉及到跨页通信——A页面的操作要影响B页面的状态——就容易掉坑。notifyListeners()时机不对、consume没处理干净、context在异步回调里已经 unmounted——这些坑,每一个都踩过。

APP目前的状态:五个页面,四套主题,AI搭配建议,数字分身试衣,会员体系。基本功能都在了。

但我知道,用户测试一圈回来,肯定还有要改的地方。

那种“这个再改一下”的消息,不会停的。

而我也应该继续打开 IDE。

*写于第 N 次 Flutter build 的间隙*

*2026年6月*