鸿蒙 ArkTS 实战:Sleep Cycle Planner 从睡眠周期规划到睡眠规划应用完整解析
鸿蒙 ArkTS 实战:Sleep Cycle Planner 从睡眠周期规划到睡眠规划应用完整解析
前言
睡眠周期规划 是一个非常适合用鸿蒙 ArkTS 来实现的轻量工具型页面。它围绕“根据起床时间和睡眠周期反推建议入睡时间,帮助用户减少起床时的困倦感。”这个明确目标,把输入、计算、结果和操作收拢在同一屏内,业务路径十分清晰。
本文直接从 Sleep Cycle Planner 的真实源码出发,拆解它如何使用 @State、Slider、Toggle、ForEach、条件渲染和计算方法,把一个小工具写得既顺手又容易维护。
工具页面的价值在于把复杂计算压缩成一眼能读懂的结果。

图示说明:本文围绕输入参数区、状态结果区、操作按钮区和辅助说明区展开,所有示例都对应项目中的真实逻辑。
一、场景定位
1.1 业务目标
根据起床时间和睡眠周期反推建议入睡时间,帮助用户减少起床时的困倦感。
1.2 用户操作路径
- 先看默认数值是否符合预期。
- 再通过滑杆、按钮或开关调整参数。
- 页面实时刷新结果。
- 根据结果做出记录、决策或确认。
1.3 技术关注点
| 关注点 | 页面体现 | 实现方式 |
|---|---|---|
| 参数输入 | 滑杆、切换、按钮 | Slider / Toggle / Button |
| 状态保存 | 数字、布尔、字符串 | @State |
| 计算逻辑 | 费用、时间、进度、换算 | 方法封装 |
| 结果反馈 | 文案、颜色、数字变化 | Text / 条件样式 |
二、页面入口
2.1 组件骨架
@Entry
@Component
struct Index {
build() {
Column() {
Text('睡眠周期规划')
}
}
}
2.2 单页工具的好处
睡眠周期规划 的状态字段数量不多,但每个字段都直接参与结果输出。单页结构能让逻辑一眼看清,不需要复杂的页面跳转。
2.3 页面布局拆分
| 区域 | 作用 | 常见组件 |
|---|---|---|
| 顶部 | 主题和核心结果 | Row、Text、Stack |
| 中部 | 参数输入 | Slider、Toggle |
| 底部 | 补充说明 | Text、Button |
三、状态设计
3.1 State 表
| 字段 | 类型 | 含义 |
|---|---|---|
| wakeHour | number | 起床小时,默认 7 |
| wakeMinute | number | 起床分钟,默认 30 |
| cycles | number | 睡眠周期数,默认 5 |
3.2 状态声明
@Entry
@Component
struct Index {
@State wakeHour: number = 7; // 起床小时,默认 7
@State wakeMinute: number = 30; // 起床分钟,默认 30
@State cycles: number = 5; // 睡眠周期数,默认 5
}
3.3 设计原则
这些状态都很贴近业务,不存在多余包装。比如金额、小时、人数、阶段、布尔开关,都是能直接解释给用户听的字段。
好的状态设计应该让人看代码就知道界面会怎么变。
四、业务数据与数组
4.1 数组内容
无数组字段:页面围绕起床时间和睡眠周期做时间换算
4.2 ForEach 示例
ForEach(this.items, (item: string, index: number) => {
Text(item).onClick(() => {
this.selected = index
})
})
4.3 索引映射
Text(this.items[this.selected])
.backgroundColor(this.selected === index ? '#7C3AED' : '#FFFFFF')
这种写法很适合固定选项和固定计算模板。
五、输入控件
5.1 Slider
Slider 在这批项目里非常常见,因为它最适合调节连续参数。
Slider({ value: this.value, min: 0, max: 100, step: 1 })
.onChange((value: number) => {
this.value = Math.round(value)
})
5.2 Toggle
Toggle 适合表示保价、会员、确认、开关等二值状态。
Toggle({ type: ToggleType.Switch, isOn: this.enabled })
.onChange((on: boolean) => { this.enabled = on })
5.3 Button
Button 适合离散动作,比如下一步、重置、增加、清零。
Button('重置')
.backgroundColor('#7C3AED')
六、交互行为
6.1 动作列表
- 滑杆调整起床小时
- 滑杆调整起床分钟
- 滑杆调整睡眠周期数
- bedMinutes 方法回推建议入睡时间
6.2 关键源码
bedMinutes(): number {
let total: number = this.wakeHour * 60 + this.wakeMinute - this.cycles * 90 - 15
while (total < 0) { total += 24 * 60 }
return total
}
6.3 动作闭环
- 滑杆调整起床小时
- 滑杆调整起床分钟
- 滑杆调整睡眠周期数
- bedMinutes 方法回推建议入睡时间
这类页面特别强调“输入即结果”。用户不需要点击提交,状态变化后结果就应该刷新。
七、公式与计算
7.1 核心公式
bedTime = wakeTime - cycles * 90 - 15
7.2 结果方法
当公式不止一步时,放进方法里最清楚:
private calc(): number {
return Math.round(1)
}
7.3 结果区域
Text('结果:' + String(value))
.fontSize(40)
.fontWeight(FontWeight.Bold)
.fontColor('#7C3AED')
八、组件细节
8.1 Text
Text 用来放金额、分钟、距离、轮次、说明,是工具页里最核心的反馈组件。
8.2 Stack
Stack 可以承载圆形背景和大数字,让结果看上去更聚焦。
Stack() {
Circle().width(190).height(190).fill('#F8FAFC')
Text('核心结果')
}
8.3 条件文案
Text(this.done ? '已完成' : '继续调整')
8.4 条件颜色
.fontColor(this.warning ? '#DC2626' : '#7C3AED')
九、布局方式
9.1 左右布局
部分页面采用左侧结果、右侧参数的结构,更适合大数字展示。
9.2 上下布局
如果需要逐步输入参数,上下布局会更顺手。
9.3 视觉层级
| 内容 | 推荐位置 | 原因 |
|---|---|---|
| 结果 | 顶部/中心 | 最先看到 |
| 参数 | 中部 | 方便拖动 |
| 说明 | 底部 | 不打扰操作 |
十、调试与验证
10.1 验证路径
- 看默认值是否正确。
- 改一个参数,确认所有结果变化。
- 检查边界值是否稳定。
- 检查文案与颜色是否同步。
10.2 日志辅助
Button('调试')
.onClick(() => {
console.info('value changed')
})
10.3 常见问题
| 问题 | 原因 | 处理方式 |
|---|---|---|
| 数值没变化 | 没写回 @State | 检查赋值 |
| 计算不对 | 公式少了括号 | 单独封装方法 |
| 文案不刷新 | Text 没绑定状态 | 改成状态表达式 |
| 超出边界 | 缺少 if 限制 | 加最大值/最小值 |
十一、扩展能力
11.1 保存历史
工具类应用很适合保存最近一次输入,方便下次继续使用。
11.2 分享结果
换算结果、计费结果和排期结果都可以导出成文本。
{
"tool": "睡眠周期规划",
"theme": "睡眠规划",
"state": "wakeHour、wakeMinute、cycles"
}
11.3 多方案比较
当同类工具需要比较不同方案时,可以把当前页面扩成左右对照模式。
十二、体验优化
12.1 单位标注
金额要带“元”,时间要带“分钟”或“小时”,重量要带“kg”,容量要带“ml”。
12.2 即时反馈
每次滑杆移动都应该立刻刷新,让用户知道自己改了什么。
12.3 参数范围
参数范围要贴合业务,不要为了演示设置过宽的区间。
十三、完整实现片段
13.1 状态骨架
@Entry
@Component
struct Index {
@State wakeHour: number = 7; // 起床小时,默认 7
@State wakeMinute: number = 30; // 起床分钟,默认 30
@State cycles: number = 5; // 睡眠周期数,默认 5
}
13.2 数据配置
// 无数组字段:页面围绕起床时间和睡眠周期做时间换算
private primaryColor: string = '#7C3AED'
13.3 交互代码
bedMinutes(): number {
let total: number = this.wakeHour * 60 + this.wakeMinute - this.cycles * 90 - 15
while (total < 0) { total += 24 * 60 }
return total
}
13.4 结果样式
Text('计算结果')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#7C3AED')
十四、可复用模式
14.1 状态模式
- number 处理金额、时长、距离、轮次。
- boolean 处理开关、会员、保价、确认。
- string 处理阶段、模式和方向。
14.2 交互模式
这类页面最常见的模式是:滑杆改数值,按钮做动作,文本直接回显。
14.3 视觉模式
大结果、小说明、主题色按钮,是工具类页面非常稳的组合。
十五、总结
15.1 参数表述
睡眠周期规划 的参数表述要保持业务可读性。用户看到 wakeHour、wakeMinute、cycles 时,应该能立刻理解这些字段对应金额、时间、数量、开关还是当前选项。
15.2 公式透明
公式 bedTime = wakeTime - cycles * 90 - 15 不应该只停留在代码里。页面通过大号结果、单位说明和辅助文案,把公式含义转成用户能直接使用的结果。
15.3 状态回放
后续如果加入历史记录,可以把每次输入和结果保存下来,形成可回放的数据流。
interface ToolHistoryItem {
title: string
input: string
result: string
createdAt: string
}
十六、总结
Sleep Cycle Planner 用简洁的 ArkTS 代码完成了 睡眠规划 场景。它围绕 wakeHour、wakeMinute、cycles 建模,围绕 无数组字段:页面围绕起床时间和睡眠周期做时间换算 组织数据,并通过 bedTime = wakeTime - cycles * 90 - 15 把输入变化转成即时结果。
这类工具页面最关键的不是页面多,而是逻辑清楚、反馈直接、边界稳定。把这些做好,鸿蒙 ArkTS 就能很自然地承载各种计算器、记录器和排期工具。
相关链接:
更多推荐



所有评论(0)