我用 HarmonyOS 写了个「饮品特调研究所」,边学 ArkUI 边调奶茶
我用 HarmonyOS 写了个「饮品特调研究所」,边学 ArkUI 边调奶茶
喝奶茶喝出个 App 来,也是没谁了。
完整效果展示
缘起
说来也挺偶然的,有一天下午想点杯奶茶,打开外卖 App 翻了半天,发现每家店的选项都大同小异——珍珠、椰果、布丁,冰度甜度来回切。我就在想,要是有个东西能让我自己随便组合,想加什么风味就加什么风味,那该多爽。
正好最近在学鸿蒙开发,ArkUI 的声明式写法看着挺顺手的,干脆拿这个需求练练手。于是就有了这个「饮品特调研究所」——一个能选基底、调冰度甜度、输入你脑子里任何奇怪风味想法,然后帮你生成一杯"专属特调"的小应用。
功能不复杂,但 ArkUI 里几个核心的东西它都用到了,拿来入门挺合适的。
技术栈一览
| 技术 | 说明 |
|---|---|
| 开发语言 | ArkTS(TypeScript 的超集,鸿蒙原生开发语言) |
| UI 框架 | ArkUI(声明式 UI 框架) |
| 目标平台 | HarmonyOS NEXT |
| 开发工具 | DevEco Studio |
应用界面设计
打开应用,首先映入眼帘的是顶部的标题“饮品特调研究所”,简洁明了地告诉用户这是一个什么样的地方。
整个界面采用了经典的卡片式布局,白色背景搭配淡灰色的功能卡片,视觉层次分明。各个功能模块从上到下依次排列:
- 饮品基底选择— 通过下拉选择器,用户可以从奶茶、特调微醺(酒)、鲜果茶、手冲咖啡四种基底中选择
- 冰度选择— 支持正常冰、少冰、去冰、常温、热饮五种选项
- 甜度调节— 通过滑动条(Slider)从 0% 到 100% 自由调节
- 口味灵感输入— 文本输入框,用户可以自由描述想要的风味
- 调配按钮— 一键生成专属配方
- 结果展示— 以卡片形式展示调配结果
这种设计思路遵循了**“从宏观到微观”**的交互逻辑:先选大类(基底),再调细节(冰度、甜度),最后注入个性(风味),整个流程自然流畅。
核心代码架构解析
1. 状态管理——应用的"灵魂"
在 ArkUI 的声明式开发范式中,状态管理是最核心的概念。当你修改一个状态变量时,UI 会自动重新渲染——这就是声明式 UI 的魅力所在。
@StatedrinkType:string='奶茶'@StateflavorInput:string=''@Statesweetness:number=50@StateiceLevel:string='正常冰'@StatemixResult:string=''这里我们定义了五个@State装饰的状态变量:
drinkType:当前选择的饮品基底,默认是"奶茶"flavorInput:用户输入的风味描述sweetness:甜度百分比,默认 50%iceLevel:冰度选择,默认"正常冰"mixResult:调配结果的展示文本
@State装饰器是 ArkUI 状态管理的基石。它告诉框架:“这个变量的变化会影响 UI,当它改变时,请重新渲染依赖它的组件。” 这种自动化的数据绑定机制,让我们无需手动操作 DOM 或调用setState,极大简化了代码逻辑。
2. 组件化布局——用声明式语法构建界面
ArkUI 的组件化思想与 SwiftUI、Jetpack Compose 类似,但 ArkTS 的语法更加贴近 TypeScript 开发者的习惯。
顶部标题
Text('饮品特调研究所').fontSize(28).fontWeight(FontWeight.Bold).fontColor('#2E3032').margin({top:50,bottom:30})一个简单的Text组件,通过链式调用设置字体大小、字重和颜色。ArkUI 的组件属性设置非常直觉化——你看到什么属性名,它就是什么意思。
下拉选择器
Row(){Text('选择基底:').fontSize(18).fontWeight(FontWeight.Medium)Select([{value:'奶茶'},{value:'特调微醺 (酒)'},{value:'鲜果茶'},{value:'手冲咖啡'}]).selected(0).value(this.drinkType).font({size:16}).onSelect((index:number,value:string)=>{this.drinkType=value;})}.width('90%').margin({bottom:20}).justifyContent(FlexAlign.SpaceBetween)这里用Row组件实现水平布局,Text作为标签,Select作为下拉选择器。当用户选择新的选项时,onSelect回调会更新drinkType状态变量,UI 随之自动刷新。
值得注意的是,Select组件的.value()属性绑定了this.drinkType,这意味着选择器的显示值始终与状态变量保持同步。这种双向绑定的思想贯穿整个 ArkUI 开发。
甜度滑动条
Column(){Row(){Text('甜度比例:').fontSize(18).fontWeight(FontWeight.Medium)Text(`${this.sweetness}%`).fontSize(16).fontColor('#007DFF')}.width('100%').justifyContent(FlexAlign.SpaceBetween)Slider({value:this.sweetness,min:0,max:100,step:10,style:SliderStyle.OutSet}).blockColor('#007DFF').trackColor('#E5E8EA').selectedColor('#007DFF').showSteps(true).onChange((value:number,mode:SliderChangeMode)=>{this.sweetness=value;})}.width('90%').margin({bottom:25})滑动条组件Slider是一个非常实用的交互控件。通过.onChange()回调,我们可以在用户拖动滑块时实时更新sweetness的值。同时,标题区域使用模板字符串${this.sweetness}%动态显示当前甜度百分比,让用户一目了然。
这种"实时反馈"的设计模式在移动端应用中非常常见——它让用户在操作过程中就能看到结果变化,而不是等到最后才看到。
口味输入框
TextInput({placeholder:'输入你想要的口味,如:乌龙茶底带点白桃香...'}).width('90%').height(60).fontSize(16).margin({bottom:35}).onChange((value:string)=>{this.flavorInput=value;})TextInput是 ArkUI 中最基础的输入组件。我们设置了占位符文本(placeholder)来引导用户输入,通过.onChange()实时捕获输入内容并更新状态变量。
3. 核心逻辑——饮品调配算法
mixDrink(){if(!this.flavorInput){this.mixResult='请先输入你想要的灵魂风味哦!';return;}this.mixResult=`【专属特调完成】\n基底:${this.drinkType}\n冰度:${this.iceLevel}\n甜度:${this.sweetness}%\n风味注入:${this.flavorInput}\n\n系统提示:配方已生成,融合了您独特的灵感,请享用这杯独一无二的饮品!`;}目前的调配逻辑相对简单,主要是一个模板字符串的拼接。但这个函数的设计预留了很大的扩展空间——未来可以对接后端大模型 API,根据用户输入的风味描述智能推荐配方,甚至生成详细的制作步骤和原料清单。
4. 条件渲染——结果展示卡片
if(this.mixResult){Column(){Text('调配结果').fontSize(18).fontWeight(FontWeight.Bold).margin({bottom:10}).fontColor('#007DFF')Text(this.mixResult).fontSize(15).lineHeight(24).fontColor('#333333')}.width('90%').margin({top:40}).padding(20).backgroundColor('#F1F3F5').borderRadius(16).shadow({radius:10,color:'rgba(0,0,0,0.05)',offsetY:5})}ArkUI 的条件渲染语法非常简洁——直接使用if语句即可。当mixResult为空字符串时(falsy),结果卡片不会显示;当用户点击调配按钮后,mixResult被赋值,卡片自动出现。
结果卡片还添加了圆角(borderRadius)和阴影(shadow)效果,让整个界面看起来更加精致和有层次感。
交互流程设计
整个应用的交互流程可以概括为以下几步:
选择基底 → 选择冰度 → 调节甜度 → 输入风味 → 点击调配 → 查看结果这种线性流程设计降低了用户的认知负担——你不需要思考"我该从哪里开始",只需要从上往下依次填写即可。每个步骤都有明确的默认值(奶茶、正常冰、50%甜度),即使用户不修改所有参数,也能直接点击调配获得结果。
设计细节与 UX 思考
1. 色彩运用
整个应用使用了蓝白灰为主色调:
- 蓝色(#007DFF):作为主色调,用于按钮、滑块、强调文字
- 白色(#FFFFFF):背景色,保持界面清爽
- 灰色(#F1F3F5):结果卡片背景,与主背景形成层次对比
- 深灰(#2E3032):标题文字,保证可读性
这种配色方案在工具类应用中非常常见,既不会显得单调,又不会过于花哨。
2. 间距与留白
代码中大量使用了margin和padding来控制间距:
- 顶部标题
margin({ top: 50, bottom: 30 }) - 每个功能模块之间保持 20-35px 的间距
- 结果卡片内部使用
padding(20)提供呼吸空间
良好的间距设计让界面不会显得拥挤,用户在操作时也能清楚地区分各个功能区域。
3. 字体层级
应用中使用了三种字体大小来建立信息层级:
- 28px:主标题,最醒目
- 18px:功能标签,中等大小
- 15-16px:内容文字和选项,辅助信息
这种清晰的字体层级让用户能够快速扫视界面并找到所需信息。
未来扩展方向
虽然目前的应用功能相对基础,但架构上已经为后续扩展做好了准备。以下是一些值得探索的方向:
1. 接入 AI 大模型
当前的调配逻辑只是简单的模板拼接,但如果我们接入一个大语言模型(比如通过 API 调用),就可以实现:
- 根据用户描述的风味智能推荐配方比例
- 生成详细的制作步骤
- 提供搭配小食的建议
- 根据季节和天气推荐饮品
2. 配方收藏与分享
- 添加收藏功能,让用户保存喜欢的配方
- 生成精美的配方卡片图片,方便分享到社交媒体
- 支持将配方导出为 PDF 格式
3. 社区功能
- 用户可以发布自己的特调配方
- 浏览和点赞其他用户的创意
- 举办"最佳特调"评选活动
4. 个性化推荐
根据用户的历史选择和偏好,智能推荐:
- 新的基底搭配
- 季节限定配方
- 用户可能喜欢的风味组合
5. AR 预览
利用 HarmonyOS 的 AR 能力,让用户在调配完成后通过 AR 预览饮品的外观效果——这会让整个体验更加生动有趣。
