我用 HarmonyOS 写了个「饮品特调研究所」,边学 ArkUI 边调奶茶

喝奶茶喝出个 App 来,也是没谁了。

完整效果展示
在这里插入图片描述

缘起

说来也挺偶然的,有一天下午想点杯奶茶,打开外卖 App 翻了半天,发现每家店的选项都大同小异——珍珠、椰果、布丁,冰度甜度来回切。我就在想,要是有个东西能让我自己随便组合,想加什么风味就加什么风味,那该多爽。

正好最近在学鸿蒙开发,ArkUI 的声明式写法看着挺顺手的,干脆拿这个需求练练手。于是就有了这个 「饮品特调研究所」——一个能选基底、调冰度甜度、输入你脑子里任何奇怪风味想法,然后帮你生成一杯"专属特调"的小应用。

功能不复杂,但 ArkUI 里几个核心的东西它都用到了,拿来入门挺合适的。

技术栈一览

技术 说明
开发语言 ArkTS(TypeScript 的超集,鸿蒙原生开发语言)
UI 框架 ArkUI(声明式 UI 框架)
目标平台 HarmonyOS NEXT
开发工具 DevEco Studio

应用界面设计

打开应用,首先映入眼帘的是顶部的标题 “饮品特调研究所”,简洁明了地告诉用户这是一个什么样的地方。
在这里插入图片描述

整个界面采用了经典的卡片式布局,白色背景搭配淡灰色的功能卡片,视觉层次分明。各个功能模块从上到下依次排列:

  1. 饮品基底选择 — 通过下拉选择器,用户可以从奶茶、特调微醺(酒)、鲜果茶、手冲咖啡四种基底中选择
  2. 冰度选择 — 支持正常冰、少冰、去冰、常温、热饮五种选项
  3. 甜度调节 — 通过滑动条(Slider)从 0% 到 100% 自由调节
  4. 口味灵感输入 — 文本输入框,用户可以自由描述想要的风味
  5. 调配按钮 — 一键生成专属配方
  6. 结果展示 — 以卡片形式展示调配结果

在这里插入图片描述

这种设计思路遵循了**“从宏观到微观”**的交互逻辑:先选大类(基底),再调细节(冰度、甜度),最后注入个性(风味),整个流程自然流畅。

核心代码架构解析

1. 状态管理——应用的"灵魂"

在 ArkUI 的声明式开发范式中,状态管理是最核心的概念。当你修改一个状态变量时,UI 会自动重新渲染——这就是声明式 UI 的魅力所在。

@State drinkType: string = '奶茶'
@State flavorInput: string = ''
@State sweetness: number = 50
@State iceLevel: string = '正常冰'
@State mixResult: 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. 间距与留白

代码中大量使用了 marginpadding 来控制间距:

  • 顶部标题 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 预览饮品的外观效果——这会让整个体验更加生动有趣。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐