鸿蒙原生应用 ArkUI 实战:实验室预约我的页 —— 任务型个人中心的四块写法
2026/9/9 13:05:01 网站建设 项目流程

鸿蒙原生应用 ArkUI 实战:实验室预约我的页 —— 任务型个人中心的四块写法

App 23「实验室设备预约」我的 Tab(ProfileTab),是个人中心页——最简 4 块结构:渐变用户卡(🔬 科研达人 + 累计使用 36 小时)+ 4 栏统计(预约记录 18/使用时长 36h/收藏设备 4/待使用 2)+ 5 菜单(预约记录/使用记录/设备收藏/联系管理员/设置)+ About(实验室设备预约 v1.0.0)。与 App 21/22 我的页同构(4 块最简 + 92% 宽 + 负边距悬浮)——是"任务型应用"的典型个人中心。本篇基于23-lab-booking/entry/src/main/ets/pages/ProfileTab.ets(约 101 行)逐段拆解,附 4 张实机截图。

一、整体结构:4 个 @Builder 的最简个人中心

ProfileTab 是系列最简洁的个人中心——4 个 @Builder:

build() { Column() { Scroll() { Column() { this.UserCard() this.StatRow() this.MenuList() this.About() } .width('100%') .padding({ bottom: D.pad + this.safeBottom + 20 }) } .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top) } .width('100%').height('100%').backgroundColor(C.bg) }

4 块顺序:UserCard(身份)→ StatRow(数据)→ MenuList(资产)→ About(关于)。

与 App 21 问卷/App 22 投票我的页 100% 同构——"任务型个人中心模板"第 3 次复用(21/22/23 连续 3 个 App 都是"4 块最简")——"任务型 App 个人中心 = 4 块"成为系列的稳定模式

项目源码开源:https://gitee.com/codenestFlow/HarmonyOSHub

二、UserCard:深青渐变 + 科研达人

UserCard 是简洁的横向用户卡:

@Builder UserCard() { Row({ space: 14 }) { Row() { Text('🔬').fontSize(32) } .width(64).height(64).backgroundColor('#33FFFFFF').borderRadius(32).justifyContent(FlexAlign.Center) Column({ space: 5 }) { Text('科研达人').fontSize(18).fontWeight(FontWeight.Bold).fontColor('#FFFFFF') Text('累计使用 36 小时').fontSize(12).fontColor('#FFFFFF').opacity(0.85) }.alignItems(HorizontalAlign.Start).layoutWeight(1) } .width('100%') .padding({ top: this.safeTop + 30, left: D.pad, right: D.pad, bottom: 44 }) .linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] }) }

关键设计

  1. 64×64 正圆头像borderRadius(32))—— 系列标准
  2. 🔬 显微镜 emoji—— 科研设备视觉符号(呼应 App 主题"实验室")
  3. "科研达人"称号—— 称号型身份(App 19"摄影爱好者"/App 21"问卷达人"/App 22"投票达人"同款)——"业务 + 达人"
  4. "累计使用 36 小时" Slogan——业务型 Slogan("累计使用" = 科研时长)——与 StatRow"使用时长 36h"一致 ✓
  5. 深青 135° 渐变——linearGradient主题色

"累计使用 36 小时"—— 科研人员的核心指标(实验时长)——"科研达人"的称号靠"使用时长"支撑(36 小时 = 做过 36 小时实验)。

bottom: 44给 StatRowmargin: -24留 20vp 实际重叠——"卡片叠加悬浮"。

渐变背景的"135° 对角线"解析

linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })—— 135° 意味着渐变从左上角到右下角。为什么选 135° 而非 90°(垂直)或 0°(水平)?

  • 90° 垂直渐变:上深下浅,视觉重心偏上,适合"标题栏"但用户卡需要整体均匀
  • 0° 水平渐变:左深右浅,横向动感强但与"头像在左、文字在右"的布局冲突
  • 135° 对角渐变:左上深 → 右下浅,与"头像左上 + 文字右侧"的视觉流一致——深色区域恰好衬托头像,浅色区域衬托文字——"渐变方向 = 内容流向"

#33FFFFFF半透明头像底色——#33= 20% 不透明度白色,在深青渐变上形成**"磨砂玻璃"效果**——头像区域不抢渐变主色,但提供视觉边界——"半透明叠加"是渐变背景上的标准头像处理

opacity(0.85)Slogan 淡化—— 称号fontColor('#FFFFFF')全不透明(主信息),Sloganopacity(0.85)(次信息)——"同色不同透明度"实现层级区分,比用不同颜色更和谐。

三、StatRow:4 栏统计

StatRow 是 4 栏统计(与 App 21/22 同款):

private stats: StatItem[] = [ { value: '18', label: '预约记录' }, { value: '36', label: '使用时长(h)' }, { value: '4', label: '收藏设备' }, { value: '2', label: '待使用' } ];

4 栏的"科研预约视角"

数字标签含义
18预约记录累计预约 18 次
36使用时长(h)累计使用 36 小时
4收藏设备收藏 4 台常用设备
2待使用2 条待使用的预约

"预约记录 + 使用时长 + 收藏设备 + 待使用"—— 科研人员的 4 个核心指标:

  • 预约记录 18—— 活跃度(约过多少次)
  • 使用时长 36h—— 投入度(用了多久)
  • 收藏设备 4—— 偏好(常用设备)
  • 待使用 2—— 待办(待处理的预约)

"使用时长 36h"= UserCard Slogan 的数据来源 ✓ ——"用户卡 Slogan = 统计指标"跨组件呼应(App 22 同款设计)。

4 栏同色C.text深色—— "颜色留给状态"。

width('92%')+margin({ top: -24 })—— 与 App 21/22 同款"卡片叠加"。

"浮动卡片"的负边距设计解析

StatRow 的margin({ top: -24 })负边距悬浮的核心——统计卡向上"侵入"UserCard 的bottom: 44padding 区域,形成 20vp 的视觉重叠:

  • UserCardbottom: 44—— 底部留白 44vp
  • StatRowmargin: -24—— 向上偏移 24vp
  • 实际重叠= 44 - 24 = 20vp —— 统计卡"骑"在用户卡底部

为什么用负边距而非 Stack 叠层?

  • Stack 方案Stack() { UserCard(); StatRow().offset({ y: -24 }) }—— 需要额外容器,且 Scroll 内 Stack 布局复杂
  • 负边距方案Column() { UserCard(); StatRow().margin({ top: -24 }) }——Column 流式布局 + 负边距微调,代码更简洁

"负边距悬浮"是系列个人中心的标志性技法——App 21/22/23 连续 3 个 App 使用同一方案——"Column + 负 margin"比"Stack + offset"更适合 Scroll 内的卡片叠加

4 栏等宽布局Row()+layoutWeight(1)每栏——4 栏自动等分 92% 宽度——"Row + layoutWeight"是等宽栏的标准写法(比 Grid 更灵活,不需要计算列数)。

四、MenuList:5 项菜单

MenuList 是 5 项菜单(与 App 21/22 同款结构):

private menus: MenuItem[] = [ { id: 1, emoji: '📋', title: '预约记录' }, { id: 2, emoji: '📝', title: '使用记录' }, { id: 3, emoji: '⭐', title: '设备收藏' }, { id: 4, emoji: '📞', title: '联系管理员' }, { id: 5, emoji: '⚙️', title: '设置' } ];

5 项菜单的"实验室业务"覆盖

菜单业务
📋 预约记录历史预约
📝 使用记录设备使用日志
⭐ 设备收藏常用设备
📞 联系管理员实验室特色(设备故障/权限申请)
⚙️ 设置通用

"联系管理员"是实验室预约的特色菜单——设备出问题/需要权限时联系实验室管理员——"特色菜单 = 业务核心"(对比 App 21"数据导出"、App 22"投票统计")。

5 项按"使用频次"排序:预约记录(高频)→ 使用记录(中)→ 设备收藏(中)→ 联系管理员(低频)→ 设置(低频)。

>箭头 + emoji + 标题三件套 —— "最简菜单结构"。

菜单项的"分组逻辑"缺失分析

App 23 的 5 项菜单是扁平列表——没有分组。真实实验室预约 App 的菜单通常需要分组

  • 第一组(我的记录):预约记录 / 使用记录 / 设备收藏
  • 第二组(帮助):联系管理员
  • 第三组(系统):设置

分组的好处:用户快速定位——"记录类"在上、"帮助"在中、"系统"在下——"功能分组 = 认知减负"

真实项目的分组实现

// 菜单分组(用 Section 分隔) Column() { // 第一组:记录 this.MenuSection([menus[0], menus[1], menus[2]]) // 间距 12vp Blank().height(12) // 第二组:帮助 this.MenuSection([menus[3]]) Blank().height(12) // 第三组:系统 this.MenuSection([menus[4]]) }

App 23 的简化:5 项菜单放一个卡片——"扁平 < 分组"——当菜单项 ≤ 5 时扁平可接受,超过 5 项建议分组。

五、MenuList 结构与 About

MenuList 与 App 21/22 同款结构(92% 宽 + Divider 0.5vp +>箭头):

@Builder MenuList() { Column() { ForEach(this.menus, (m: MenuItem, idx: number) => { Row({ space: 12 }) { Text(m.emoji).fontSize(18) Text(m.title).fontSize(14).fontColor(C.text).layoutWeight(1) Text('>').fontSize(14).fontColor(C.textDim) } .width('100%').padding({ left: 14, right: 14, top: 14, bottom: 14 }) .onClick(() => { promptAction.showToast({ message: m.title }); }) if (idx < this.menus.length - 1) { Divider().color(C.stroke).strokeWidth(0.5) } }, (m: MenuItem) => m.title) } .width('92%').margin({ top: 16 }).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke }) }

About是"实验室设备预约 / Version 1.0.0"双行(与 App 21/22 同款)——opacity(0.7)版本号淡化。

Divider 分割线的"最后一项跳过"逻辑

if (idx < this.menus.length - 1) { Divider() }——最后一项不画分割线。这是列表分割线的标准写法:

  • 为什么不用border-bottom—— 最后一项会有多余的底线,视觉上"断开"
  • 为什么不用Divider()无条件渲染?—— 同上,最后一项底部多一条线
  • idx < length - 1条件渲染——只在项与项之间画线,首尾无线 ——"分割线 = 项间分隔"而非"项底装饰"

strokeWidth(0.5)的"细线"选择—— 0.5vp 比 1vp 更精致——"细分割线 = 高级感"(iOS 设置页同款 0.5vp 细线)——粗线(1vp+)显得"廉价",细线(0.5vp)显得"精致"。

color(C.stroke)用主题色—— 不硬编码#E0E0E0——"分割线跟随主题"(暗色模式自动适配)。

六、@State 数量 = 0(系列第 7 个"0 @State 个人中心")

ProfileTab0 个 @State—— 所有数据private不可变。这是系列第七个"0 @State"个人中心(App 13/17/20/21/22/23 + 各数据页)——"展示型页面 = 0 @State"规律持续成立。

4 个 Tab 的 @State 分布(App 23):

页面@State类型
首页1(activeCat)分类 Chip
设备0纯展示详情
预约1(slot)时段真单选
我的0纯展示

App 23 是"任务型 2 状态"的代表——首页/预约各 1 个状态(分类/时段),设备/我的纯展示。

七、数据一致性

"累计使用 36 小时"= StatRow"使用时长 36h" ✓——Slogan 与统计精确对应。

"待使用 2"vs 预约页记录(今天/明天 2 条待使用)✓——"我的页待使用 2 = 预约页待使用 2 条"——跨页数据一致。

"预约记录 18"vs 预约页 4 条记录——18 是累计(含已结束)、4 条是近期列表——**"统计累计 vs 列表近期"**口径合理。

八、与 App 21/22 我的页的"三连同构"

App 21 问卷、App 22 投票、App 23 实验室——3 个"任务型 App"的个人中心 100% 同构

组件App 21(问卷)App 22(投票)App 23(实验室)
UserCard📊 问卷达人🗳️ 投票达人🔬 科研达人
Slogan已创建 8 份参与 28 次累计使用 36 小时
StatRow我的问卷/填写/收集/进行创建/参与/历史/进行预约/时长/收藏/待使用
MenuList我的问卷/填写/导出/模板/设置参与/创建/历史/统计/设置预约/使用/收藏/管理员/设置
About在线问卷调查校园投票管理实验室设备预约

"3 连任务型 App"证明"4 块个人中心"是任务型应用的稳定模板——读者做任何"任务型"产品(工具/预约/打卡)可直接套用。

九、"累计使用 36 小时"的 Slogan 设计

App 23 UserCard Slogan"累计使用 36 小时"值得从文案角度分析:

"累计使用 X 小时"是科研/工具类 App 的"投入型 Slogan"

  • App 22 投票:"参与 28 次投票"(次数型
  • App 23 实验室:"累计使用 36 小时"(时长型

"次数 vs 时长"的选择

  • 次数(参与 28 次)——适合"任务型"(一次一个动作)
  • 时长(使用 36 小时)——适合"投入型"(科研要长时间投入)

"科研达人"的身份靠"时长"支撑——36 小时实验 = 做了 36 小时科研——"时长的积累感"比"次数的完成感"更适合科研

Slogan 的"3 要素"(系列标准):

  1. 数字(36)——精确可信
  2. 动词(累计使用)——投入描述
  3. 单位(小时)——量纲明确

**"数字 + 动词 + 单位"**是投入型 Slogan 的标准——读者做"工具/科研/学习"类 App 时,用"累计 X 小时"比"已使用 X 天"更有"投入感"。

十、"4 栏统计"的科研视角

App 23 的 4 栏统计(预约记录/使用时长/收藏设备/待使用)——"科研工作者"的数据画像

数字维度科研含义
预约记录 18行为预约了多少次设备
使用时长 36h投入在实验室花了多少时间
收藏设备 4偏好常用哪几台设备
待使用 2待办还有哪些预约没去

"行为 + 投入 + 偏好 + 待办"4 维度——完整刻画"科研工作者的实验室使用画像"——对比 App 21 问卷的"创建+参与+收集+进行"(双向 UGC 视角)——"统计维度跟随业务角色"

真实项目的"统计聚合"

// 统计从预约记录聚合 const stats = { '预约记录': bookings.length, '使用时长': bookings.reduce((sum, b) => sum + b.duration, 0), '收藏设备': favorites.length, '待使用': bookings.filter(b => b.status === '待使用').length };

"统计 = 业务数据的聚合"——不是硬编码,而是从预约记录/收藏列表实时计算——**"数据驱动统计"**是真实项目的正确做法。

十一、"联系管理员"菜单的"人工兜底"

App 23 的"📞 联系管理员"菜单是**"人工兜底"入口**——工具类 App 的必备设计:

"人工兜底"的价值

  • 自动流程解决 80%(预约/查询/统计)
  • 人工兜底解决 20%(设备故障/权限问题/特殊需求)

"联系管理员"的 3 种形态

  1. 电话(📞 图标暗示)——最直接
  2. 在线客服(IM 聊天)
  3. 工单系统(提交问题,管理员处理)

真实实验预约 App 的"联系管理员"场景

  • 设备故障(显微镜坏了)
  • 权限申请(特殊设备需要导师批准)
  • 时段调整(临时改预约)
  • 异常处理(设备损坏报告)

"人工兜底 = 用户安全网"——工具类 App 必须留"人工入口"——"机器做不到的、人来做"

十二、App 23 与"科研数字化"的完整闭环

App 23 实验室预约是"科研数字化"的一个环节——完整"科研数字化"生态

设备预约(App 23)→ 实验数据 → 论文写作 → 成果管理 ↑ ↓ └──────── 成果反哺(新设备采购) ←────┘

"科研数字化"的 3 层

  1. 基础设施(App 23)——设备/场地/耗材的预约管理
  2. 数据采集(进阶)——实验数据自动记录(传感器)
  3. 知识管理(进阶)——文献/笔记/论文(App 24 研究管理?)

App 23 是"科研基础设施"的最简版本——读者做"科研数字化"产品时,从"设备预约"(最刚需)切入是最佳路径——"先解决预约、再扩展数据"

真实"科研数字化"产品(如"超级计算平台"的预约模块)——设备预约 + 数据 + 计费 + 审批的完整系统——App 23 是它的"预约"子模块

十三、总结

App 23 我的页解析完毕。4 块最简结构(UserCard + StatRow + MenuList + About)+ 深青渐变 + 4 栏统计 + 5 菜单是核心组件。"科研达人"的业务身份 + "累计使用 36 小时"的投入型 Slogan + "预约/时长/收藏/待使用"4 维画像 + "联系管理员"人工兜底——是实验室预约类 App 个人中心的典型设计。与 App 21/22 我的页 100% 同构——"任务型个人中心模板"第 3 次复用,证明"4 块最简"是任务型应用的稳定模式。0 @State 个人中心——纯展示页,所有数据硬编码在private数组中,真实项目应从数据库聚合。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询