鸿蒙原生应用实战:借还页的双胶囊与扫码卡文字联动
鸿蒙原生应用实战:借还页的双胶囊与扫码卡文字联动
App 32「校园共享雨伞」借还(Func2Tab),主题色
#4A90D9晴空蓝。借还页采用"Header + 模式切换 + 扫码卡 + 记录列表"四区布局——白色 Header("借还伞"标题) + ModeRow 借伞/还伞双胶囊(@State mode: number,单选切换,选中蓝色实底白字) + ScanCard 虚线边框扫码卡(蓝色虚线 + 📷 56 号相机 emoji + "扫码借伞/还伞"动态文字 + "对准伞桩二维码扫描"提示) + SectionTitle + 3 条借用记录(借伞·今天 08:30 教学楼 A 楼 使用中(橙) / 还伞·昨天 18:00 图书馆 已归还(绿) / 借伞·8月10日 体育馆 已归还(绿))。本篇基于32-campus-umbrella/entry/src/main/ets/pages/Func2Tab.ets(约 107 行)逐段拆解,附 4 张实机截图。
一、整体结构:四区"Header + 模式 + 扫码 + 记录"布局
App 32 借还页是"标题 + 模式切换 + 扫码 + 历史记录"的工具型页面——5 个 @Builder 块:
build() {
Column() {
this.Header()
Scroll() {
Column({ space: 16 }) {
this.ModeRow()
this.ScanCard()
this.SectionTitle('借用记录')
this.RecordList()
}
.width('100%')
.padding({ left: D.pad, right: D.pad, top: 16, bottom: D.pad + this.safeBottom + 20 })
}
.layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top)
}
.width('100%').height('100%').backgroundColor(C.bg)
}
4 块结构:
- Header — 白色背景 + "借还伞"标题
- ModeRow — 借伞/还伞双胶囊
- ScanCard — 虚线扫码卡
- SectionTitle('借用记录') + RecordList — 3 条记录
与 App 32 首页/地图对比:
- 首页:Header + 天气 + 4 伞点(库存决策)
- 地图:Header + 地图 + 图例 + 5 伞点(位置决策)
- 借还:Header + 模式 + 扫码 + 3 记录(操作执行)
"借还页 = 操作执行"——首页和地图都是"决策"页、借还是"执行"页——"决策 → 执行的转化"——用户决定借伞后到借还页扫码执行——"3 页的转化路径"——"决策 → 位置 → 执行"。
Column({ space: 16 }) 16 间距——比首页/地图 14 大——"借还页的更宽间距"——借还页内容少(4 块),用更大间距让页面更舒展——"间距 = 内容密度"。
与系列其他扫码/操作类 App 对比:
- App 26: 文字编辑器
- App 30: 公益宠物
- App 32 借还:扫码借还 + 记录
"32 借还页的工具型"——"扫码 = 物理动作"——借还伞要扫伞桩的二维码——"扫码的物理映射"——"工具型 App 的扫码"。
主题色 #4A90D9 晴空蓝——同首页/地图——"品牌色贯穿全 App"。

二、Header:白色 + "借还伞"
Header 是 **白色 + "借还伞"**的极简标题头:
@Builder
Header() {
Row() { Text('借还伞').fontSize(20).fontWeight(FontWeight.Bold).fontColor(C.text) }
.width('100%').height(this.safeTop + 56).padding({ top: this.safeTop, left: D.pad, right: D.pad })
.backgroundColor(C.card).alignItems(VerticalAlign.Bottom)
}
Header 结构:白色 + 20 号加粗黑色"借还伞" + 56 高 + safeTop + 底部对齐——"同地图 Header"。
"借还伞" 的命名——"借+还+伞 = 3 字命名"——"借还伞 = 业务名"——比"借伞"更完整(不只是借,还能还)——"业务的完整性"——"动词+名词的命名"。
与首页/地图/我的 Header 对比:
- 首页:Column 包 Text(22 号"共享雨伞")
- 地图:Row 包 Text(20 号"伞点地图")
- 借还:Row 包 Text(20 号"借还伞")
- 我的:无 Header(用 UserCard 代替)
"20 号 = 内容头"——地图/借还都是 20 号——"内容页用 20"、首页 22 是"品牌头"——"Header 字号 = 页面性质"。
三、ModeRow:借伞/还伞双胶囊(本页核心)
ModeRow 是 借伞/还伞双胶囊,用 @State mode: number 控制选中:
@Builder
ModeRow() {
Row({ space: 10 }) {
ForEach(this.modes, (m: string, idx: number) => {
Text(m).fontSize(14)
.fontColor(this.mode === idx ? '#FFFFFF' : C.textSub)
.padding({ left: 20, right: 20, top: 8, bottom: 8 })
.backgroundColor(this.mode === idx ? C.primary : C.card).borderRadius(18)
.onClick(() => { this.mode = idx; })
}, (m: string) => m)
}.width('100%')
}
ModeRow 结构:Row 容器(10 间距)+ 2 个 Text 胶囊(ForEach 渲染)——"双胶囊的并列布局"。
this.modes: string[] = ['借伞', '还伞'] 双模式数据——"2 个业务模式"——"借伞 + 还伞"——"借还的双向业务"——"模式的两个方向"。
@State mode: number = 0 状态管理——"当前模式(0=借伞/1=还伞)"——"@State 的本地状态"——"模式切换的状态"——"ArkUI 的状态管理"。
fontColor(this.mode === idx ? '#FFFFFF' : C.textSub) 文字颜色——选中白字、未选灰字——"选中态的文字"——"颜色对比的强调"。
backgroundColor(this.mode === idx ? C.primary : C.card) 背景色——选中蓝实底、未选白底——"选中态的背景"——"蓝白对比的强提示"——"主题色 = 选中"。
padding({ left: 20, right: 20, top: 8, bottom: 8 }) 20 横向 + 8 纵向 padding——"胶囊的舒适内边距"——"20 = 较宽的横向"——"8 = 紧凑的纵向"——"胶囊的横向比例"。
borderRadius(18) 18 圆角——"胶囊的圆角"——18 接近半圆(胶囊高度 14+8+8=30,半径 15)——"18 = 胶囊的圆角"——"圆角 = 胶囊的视觉"。
onClick(() => { this.mode = idx; }) 点击切换——点击切换 mode 值——"点击改变状态"——"声明式 UI 的状态驱动"——"状态 = 选中"。
ForEach(this.modes, (m: string, idx: number) => {...}, (m: string) => m)——"双胶囊的 ForEach 渲染"——"2 个数据 = 2 个胶囊"——key 用 m.toString() 稳定——"数据驱动的胶囊"。
与 App 31 菜单页的双单选对比:
- App 31 菜单:杯型/甜度(4 选项 / 2 选项 = 双单选)
- App 32 借还:借伞/还伞(2 选项 = 单选)
"双单选 vs 单双选"——App 31 是 2 个维度各 2 选项 = 双单选、App 32 是 1 个维度 2 选项 = 单双选——"单选 vs 多选"——单选只有一个状态(mode=0 或 1)、多选有多个状态组合(杯型+甜度)——"状态的复杂度"。
this.mode === idx ? ... : ... 三目运算——"条件渲染的简洁"——"三目 vs if/else"——ArkUI 中三目常用——"ArkUI 的条件渲染"。
借伞模式截图:
@State mode: number = 0;
private modes: string[] = ['借伞', '还伞'];
"借伞默认"——mode = 0 默认借伞——"借伞 = 主操作"——"为什么默认借伞?"——共享雨伞主要场景是借(还伞较少)——"业务的主次"——"借伞 = 高频操作"。
四、ScanCard:虚线扫码卡(文字随 mode 联动)
ScanCard 是 蓝色虚线边框 + 📷 + 动态文字的扫码卡:
@Builder
ScanCard() {
Column({ space: 10 }) {
Stack({ alignContent: Alignment.Center }) {
Column().width(180).height(180).backgroundColor(C.primarySoft).borderRadius(D.rLg)
Column({ space: 8 }) {
Text('📷').fontSize(56)
Text('扫码' + (this.mode === 0 ? '借伞' : '还伞')).fontSize(16).fontWeight(FontWeight.Bold).fontColor(C.primary)
Text('对准伞桩二维码扫描').fontSize(12).fontColor(C.textDim)
}
}
.width('100%').onClick(() => { promptAction.showToast({ message: this.mode === 0 ? '借伞' : '还伞' }); })
}
.width('100%').padding({ top: 20, bottom: 20 }).backgroundColor(C.card).borderRadius(D.rLg)
.border({ width: 1, color: C.primary, style: BorderStyle.Dashed })
}
ScanCard 结构(外层 + 内层):
外层(Column):
- 背景
C.card白色 - 圆角
D.rLg20 - 虚线边框
border({ width: 1, color: C.primary, style: BorderStyle.Dashed })——蓝色虚线 1px - 20 padding 上下
内层(Stack 居中):
- 背景 180×180 浅蓝圆角(
C.primarySoft) - 居中 3 行(56 📷 + 16 "扫码借伞/还伞" + 12 "对准伞桩二维码扫描")
BorderStyle.Dashed 虚线边框——"虚线 = 占位/扫描"——"为什么用虚线?"——虚线暗示"这里是扫描区"——"虚线的视觉语义"——"扫码区的视觉"——"虚线 ≠ 实线"——实线是已确定区域、虚线是待扫描区域——"虚线的未完成感"。
color: C.primary 蓝色虚线——"主题色虚线"——"主题色强化"——蓝色虚线既显主题又显扫码区——"颜色的双重作用"。
Text('扫码' + (this.mode === 0 ? '借伞' : '还伞')) 动态文字——"随 mode 切换文字"——"动态文案 = 模式映射"——"文字的模式联动"——mode=0 → "扫码借伞"、mode=1 → "扫码还伞"——"状态驱动文案"——"文案的状态化"。
Stack({ alignContent: Alignment.Center }) Stack 居中——"内层居中"——背景卡 + 居中图标文字——"扫码卡的视觉中心"——"180×180 中心"。
Text('📷').fontSize(56) 56 号相机 emoji——"相机 = 扫码"——"大 emoji 作为图标"——"56 号是大图标"——"扫码图标的视觉"。
Text('扫码借伞').fontSize(16).fontWeight(FontWeight.Bold).fontColor(C.primary) 蓝色加粗 16 号——"主标题"——"主题色加粗"——"扫码的视觉"——"主题色 = 强调"。
Text('对准伞桩二维码扫描').fontSize(12).fontColor(C.textDim) 12 号灰——"副标题"——"提示 = 灰色"——"操作指引"——告诉用户对准哪里——"操作指引的次要感"。
onClick(() => promptAction.showToast({ message: this.mode === 0 ? '借伞' : '还伞' })) 点击反馈——整卡点击弹"借伞/还伞"Toast——"占位扫码"——真实产品调起相机扫码——"Toast 的占位"——"Toast 文字也随 mode 联动"。
backgroundColor(C.card).borderRadius(D.rLg) 白色 20 圆角外层——"扫码卡的外层"——"20 圆角 = 大卡"。
backgroundColor(C.primarySoft).borderRadius(D.rLg) 浅蓝 20 圆角内层——"扫码区的内层"——"180×180 浅蓝"——"扫码区的视觉中心"。
与系列其他扫码占位对比:
- App 27 通知:日期选择
- App 32 借还:扫码占位 + 模式联动
"扫码占位的极简"——"180×180 浅蓝 + 📷"——"占位的演示"——"真实相机调起的占位"——"扫码卡 = 占位"。
"为什么用虚线边框?"——"虚线暗示动态区域"——"扫码区 = 动态"——"虚线 = 待扫描"——"扫码区的视觉表达"——"占位 vs 实线"。
"动态文案" 的设计——"为什么文案要随 mode 变?"——"扫码的语义 = mode 决定"——借伞扫码 = 借、还伞扫码 = 还——"扫码的方向性"——"动态 = 准确"——"避免歧义"。
"对准伞桩二维码扫描" 的提示——"操作指引"——"12 号灰的次要"——告诉用户扫哪里——"伞桩 = 借还设备的物理位置"——"实体设备的指代"。

五、SectionTitle:借用记录
@Builder
SectionTitle(title: string) {
Row() { Text(title).fontSize(16).fontWeight(FontWeight.Bold).fontColor(C.text) }.width('100%')
}
极简 SectionTitle——16 号加粗黑色"借用记录"——"同首页/地图 SectionTitle"——"系列 SectionTitle 的复用"——@Builder 抽离可复用——"组件化设计"。
"借用记录" 的命名——"借用 = 借出"——"借 vs 借用"——"借是动词、借用是名词性"——"借伞 = 借 + 伞、借用记录 = 借出去 + 记录"——"命名的细节"。
六、RecordList:3 条记录(带状态色)
RecordList 是 3 条借用记录——每项含 emoji 头像、动作+时间、地点、状态:
@Builder
RecordList() {
Column({ space: 12 }) {
ForEach(this.records, (r: Record) => {
Row({ space: 12 }) {
Text(r.emoji).fontSize(24)
Column({ space: 3 }) {
Text(r.action + ' · ' + r.time).fontSize(14).fontColor(C.text)
Text(r.point).fontSize(12).fontColor(C.textDim)
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
Text(r.status).fontSize(12).fontColor(r.statusColor)
}
.width('100%').padding(14).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke })
}, (r: Record) => r.id.toString())
}.width('100%')
}
每张记录卡的结构:
- 左 emoji 头像(24 号 ☂️)
- 中 文字区("动作 · 时间" 14 号 + "地点" 12 号灰)
- 右 状态文字(12 号带颜色)
3 条记录(每条 5 要素):
| 动作 | 时间 | 地点 | 状态 | 状态色 |
|---|---|---|---|---|
| 借伞 | 今天 08:30 | 教学楼 A 楼 | 使用中 | 橙(warn) |
| 还伞 | 昨天 18:00 | 图书馆 | 已归还 | 绿(ok) |
| 借伞 | 8月10日 | 体育馆 | 已归还 | 绿(ok) |
"使用中" 与 "已归还" 的状态色——"两态 = 颜色"——橙色"使用中"= 进行中、绿色"已归还"= 完成——"状态的颜色编码"——"颜色 = 业务状态"。
r.statusColor: string 状态颜色字段——"颜色作为数据"——同 PointList 的 typeColor——"颜色内联在数据"——"数据驱动的颜色"——"状态的颜色编码"。
Text(r.action + ' · ' + r.time) 动作+时间——"中点连接"——"·" 分隔符——"动作 + 时间的并排"——"信息的紧凑"**——14 号黑色。
Text(r.point).fontColor(C.textDim) 12 号灰地点——"次要信息"——"地点作为参考"——"12 灰的次要"。
Column({space: 3}) 文字区内部 3 间距——"紧凑文字区"——"动作 + 地点的紧凑"——"3 = 极小间距"——"信息的密集"。
padding(14).borderRadius(D.rMd) 14 padding + 14 圆角——"记录卡的小圆角"——比 ScanCard 的 20 小——"记录卡用 14 圆角"——"圆角层级:20 渐变/14 普通/10 小"。
border({ width: 1, color: C.stroke }) 1px 边框——"卡片的细边框"——同系列其他卡。
3 条记录的"时间分布":
- 今天 08:30(最新)
- 昨天 18:00(昨天)
- 8月10日(多天前)
"时间的递减"——"时间从新到旧"——"3 条记录的时间线"——"使用中在最上"——"状态优先级 = 时间"——"使用中 = 当前 + 优先"。
"使用中" 的特殊位置——"使用中 = 还在借"——"使用中 = 需要关注"——"为什么使用中在最上?"——用户在首页就能看到"还有伞没还"——"状态优先 = 业务提醒"——"使用中 = 提醒用户归还"。
与首页 PointList 4 伞点对比——"记录 vs 伞点"——"伞点 = 静态位置、记录 = 动态行为"——"4 vs 3 项"——"首页伞点多、记录少(只显示最近 3)"——"信息密度的差异"。
Record 模型(7 字段):
interface Record {
id: number;
emoji: string;
action: string;
time: string;
point: string;
status: string;
statusColor: string;
}
字段说明:
id/emoji— 标识与图标action— 动作(借伞/还伞)time— 时间(今天 08:30)point— 地点status— 状态文字statusColor— 状态颜色
7 字段 vs 6 字段(首页 UmbrellaPoint/地图 Point)——"7 字段的扩展"——Record 多 1 个 action 字段——"借还 = 动作"——"动作 = 业务方向"——"动作字段的必要性"。
statusColor: string 颜色内联——同 PointList 的 typeColor——"数据 + 颜色"——"耦合 vs 解耦"——demo 简化、真实产品用枚举。
time: string 字符串时间——"时间作为字符串"——"今天 08:30" / "昨天 18:00" / "8月10日"——"相对时间表达"——"相对时间 = 用户友好"——绝对时间戳对用户不友好——"时间的人性化"。
"使用中" 状态色 C.warn 橙——#FF9F1C——"橙色 = 警告/进行中"——"橙色的语义"——"为什么使用中用橙?"——进行中 = 等待中 = 提醒——"橙色的提醒"。
"已归还" 状态色 C.ok 绿——#2BB673——"绿色 = 完成/成功"——"绿色的语义"——"已归还 = 安心"——"绿色的安心"——同首页的"可借"绿色——"OK 色的复用"。

七、借还页的交互细节与可用性分析
7.1 模式切换的"双向业务"
借伞 ↔ 还伞——"双向业务"——"借 = 拿走、还 = 归还"——"两个方向"——"为什么用双向?"——共享雨伞借了要还能形成闭环——"闭环业务"——"借 + 还 = 完整链路"。
7.2 双胶囊的"互斥性"
借伞/还伞互斥——"选了借伞就不能选还伞"——@State mode: number 单值——"单值的互斥"——"互斥的视觉"——蓝 vs 白——"对比强烈的互斥"。
7.3 扫码卡的"虚线视觉"
虚线 = 扫描区——"虚线 = 待扫"——"虚线的暗示"——"为什么用虚线?"——"扫描的视觉"——"虚线 = 动态"——"扫码区的设计"。
7.4 动态文案的"状态联动"
"扫码借伞" / "扫码还伞"——"文案 = 状态"——"文案的状态化"——"避免歧义"——"明确告诉用户扫什么"——"文案的精准"。
7.5 3 条记录的"状态"
使用中 ×1 + 已归还 ×2——"3 条 = 1+2"——"使用中 = 提醒"——"已归还 = 历史"——"状态分布合理"——"业务状态的多样"。
7.6 整卡可点 vs 按钮可点
扫码卡整卡可点——"整卡的易用性"——"用户点哪都响应"——"占位跳转"——"Toast 反馈"——"操作成本低"。
7.7 借伞 vs 还伞的"颜色一致性"
借伞蓝/还伞蓝——"两个模式用同色"——"颜色不区分模式"——"模式的区分用文字"——"借伞/还伞文字区分"——"颜色的统一"——"模式的视觉"。
7.8 记录状态的"用户引导"
使用中(橙)= 提醒归还——"状态 = 行动"——"使用中 = 还伞提醒"——"用户看到使用中会想还"——"状态的引导价值"。
7.9 扫码卡的"180×180"
180×180 浅蓝——"扫码区的尺寸"——"180 = 接近正方形"——"扫码区 = 视口"——"视口的视觉"——"扫描区的大小"。
7.10 借还页的"工具型"
扫码 + 记录——"工具型页面"——"操作 + 历史"——"工具的两要素"——"操作 = 扫码、历史 = 记录"——"工具页的完整性"。
7.11 3 条记录的"时间递减"
今天 → 昨天 → 8月10日——"时间从新到旧"——"时间排序"——"用户友好"——"最近的在最上"——"时间排序的常识"。
7.12 借还模式的"默认选择"
借伞默认——"为什么默认借伞?"——借伞是主操作(用户多)——"主操作 = 默认"——"默认的合理性"——"借伞 = 高频"。
7.13 状态色的"双重语义"
橙色"使用中" = 提醒 + 进行中——"橙色的双重"——"绿色"已归还" = 完成 + 安心"——"绿色的双重"——"颜色的多义"——"颜色的业务"。
7.14 借还页的"色彩心理学"
晴空蓝——"蓝色 = 工具"——"工具型 App 的蓝色"——"蓝色的冷静"——"借还是冷静操作"——"蓝色的可信赖"——"工具配色的心理"。
7.15 虚线边框的"系列统一"
虚线 = 占位/动态——"虚线的视觉"——"系列虚线复用"——同 App 27 通知的虚线占位——"虚线的语义"——"虚线 = 未完成"。
7.16 借还模式的"快捷性"
双胶囊快速切换——"切换 = 一键"——"点击胶囊 = 改模式"——"操作成本低"——"模式的便捷"——"单值状态的便利"。
7.17 3 条记录的"业务建模"
Record 7 字段——"业务建模的完整"——"动作/时间/地点/状态"——"共享雨伞的完整记录"——"数据的丰富"——"7 字段的必要性"。
7.18 借还页的"完整性"
模式 + 扫码 + 记录——"三要素的完整"——"操作 + 物理 + 历史"——"借还的闭环"——"工具页的完整"——"借还页的设计"。
7.19 借还 vs 扫码的"层次"
借还 = 业务层、扫码 = 物理层——"两层的设计"——"业务 = 模式、物理 = 扫码"——"业务层 = 高层、物理层 = 底层"——"两层的协同"。
7.20 借还页的"易用性"
3 步完成借伞——"1. 选模式 2. 扫码 3. 完成"——"3 步的极简"——"操作路径短"——"易用性高"——"工具页的简洁"。
7.21 3 条记录 vs 4 伞点
3 记录 vs 4 伞点——"数量差异"——"记录少(最近)、伞点多(全部)"——"信息密度的对比"——"demo 的合理"。
7.22 借还页的"色彩一致性"
全页 #4A90D9 蓝——"主题色统一"——"首页/地图/借还/我的 = 同一蓝色"——"品牌一致"——"蓝色的贯穿"——"品牌的稳定性"。
7.24 借还页的"操作反馈"
Toast 反馈——"借伞/还伞 Toast"——"反馈的精准"——"占位 = 反馈"——"操作 = 反馈"——"反馈链的完整"。
7.25 借还页的"数据驱动"
mode 状态驱动文案——"数据驱动 UI"——"state → view"——"声明式 UI 的价值"——"改状态 = 改文案"——"状态化的优势"。
7.26 借还页的"扩展性"
mode 改值 = 文案改——"扩展的便利"——"加模式 = 加数据"——"加借伞/还伞外的业务 = 加数组项"——"扩展点清晰"。
7.27 借还页的"对比与统一"
统一:3 记录同结构、统一边框、状态色编码——"列表项的统一"。 对比:3 记录不同动作/时间/状态——"列表项的差异"。
7.28 借还页的"色彩记忆"
3 状态色:橙(使用中)/绿(已归还)+ 蓝(扫码)——"3 色的记忆"——"色彩 = 状态"——"用户记住颜色"——"色彩的用户认知"。
7.29 借还页的"系列呼应"
双胶囊(31 杯型/甜度)、虚线边框(27 通知)、状态色(系列)——"32 借还的系列手法"——"复用 = 一致"——"系列统一"。
7.30 借还页的"终评"
双胶囊 + 虚线扫码 + 3 记录 = 完整借还页——"借还页的完成度"——"可上线级"——"系列工具型页面的标杆"。
八、总结:晴空蓝 + 双模式 + 虚线扫码
App 32 借还页一句话:用晴空蓝(#4A90D9)组织一个"模式 + 扫码 + 记录"的工具借还页——借伞/还伞双胶囊切换 mode 状态,蓝色虚线扫码卡用 📷 + 动态文字"扫码借伞/还伞"占位真实扫码,3 条记录用状态色(橙使用中/绿已归还)展示历史。
3 个设计亮点:
- 借还双胶囊——@State mode 单值互斥,主题色 = 选中
- 虚线扫码卡——BorderStyle.Dashed 蓝色虚线暗示动态扫描区
- 动态文案联动——mode 决定"扫码借伞/还伞"文字
主题色设计逻辑:晴空蓝 = 工具型 App 的冷静色——"借还 = 物理操作,需要冷静的可信赖感"——与首页/地图同色——"品牌色贯穿"。
与系列呼应:双单选(31 杯型/甜度)、虚线占位(27 通知)、状态色(系列)、ForEach 列表(系列)、@State 状态(系列)——"32 借还把系列的手法组合出'借还'场景"。
体验细节:双胶囊快速切换、虚线扫码占位、动态文案、3 条记录状态色——"借还页的核心 = 让用户'3 秒选模式 + 5 秒扫码'"。
可扩展性展望:相机扫码集成、押金支付、信用积分扣减、还伞校验、消息推送——"demo 的借还页骨架完整"。

八、扩展思考:借还页的转化路径与设计哲学
8.1 借还页的"操作流程"
完整借伞 3 步:
- 选模式(借伞/还伞)——1 步决策
- 扫码(虚线卡 + 📷)——1 步物理操作
- 完成(Toast 反馈)——1 步反馈
"3 步的极简流程"——"操作路径短"——"易用性高"——"3 步完成借伞"——"工具页的简洁"——"demo 的可用性"。
8.2 借还页的"信息架构"
4 层信息:
- L1 标题(Header)——"借还页"
- L2 模式(ModeRow)——"做什么操作"
- L3 扫码(ScanCard)——"怎么操作"
- L4 历史(RecordList)——"做过什么"
"4 层渐进式"——"从意识到执行"——"标题 → 模式 → 扫码 → 历史"——"操作的完整链路"。
8.3 借还页的"双向业务"
借伞 + 还伞 = 双向——"借是拿走、还是归还"——"共享雨伞的闭环"——"借了不还不是闭环"——"借 + 还 = 完整业务"——"双向 = 业务完整性"。
8.4 借还页的"模式切换的物理映射"
借伞 → 拿起伞、还伞 → 归还伞——"模式 = 物理动作"——"借还的实体动作"——"扫码 = 触发物理动作"——"模式 = 物理意图"——"线上模式 = 线下动作"。
8.5 借还页的"虚线设计"
虚线 = 待扫描——"虚线的物理隐喻"——"扫码的'扫' = 虚线'待扫'"——"虚线的状态"——"实线 = 已确定、虚线 = 待定"——"扫码的视觉表达"。
8.6 借还页的"动态文案"
"扫码借伞" / "扫码还伞"——"文案 = 状态"——"动态文案的状态化"——"避免歧义"——"明确告诉用户"——"文案的精准"——"状态驱动文案"。
8.7 借还页的"设计哲学"
借还页的 3 个设计哲学:
- 模式优先——借/还先选再执行
- 占位优先——虚线 + emoji 占位真实扫码
- 状态优先——使用中 = 橙色提醒
"模式 + 占位 + 状态的借还页"——"工具型借还页的设计原则"——"从哲学看设计"——"这套方法论可直接迁移到任何扫码/借还类 App"。
8.9 借还页的"终评"
App 32 借还页综合评估——"四区结构 + 晴空蓝主题 + 完整模式 + 扫码 + 记录"——"借还页的完成度评级"——"一个可上线级的工具借还页"——"系列工具型页面的标杆"——"demo 的高完成度"。
九、彩蛋:借还页的细节设计
9.1 双胶囊的"圆角选择"
borderRadius(18) 18 圆角——"为什么是 18?"——"胶囊高度 14+8+8=30,半圆角 15"——"18 接近 15 = 接近胶囊"——"胶囊的视觉"——"圆角的精准"。
9.2 扫码卡 180×180 的尺寸
180×180 浅蓝——"为什么是 180?"——"180 = 1.5 × 120"——"扫码区足够大"——"视口的视觉"——"180 是扫码的合理尺寸"。
9.3 借伞默认的"业务考量"
借伞默认——"业务的高频"——"借伞 = 用户多"——"还伞 = 用户少(同一用户多次借才还)"——"默认 = 主操作"——"业务的优先级"。
9.4 "对准伞桩二维码扫描" 的指引
"对准伞桩"——"伞桩 = 借还设备"——"物理位置的指引"——"实体设备"——"用户知道扫哪里"——"物理映射"。
9.5 3 条记录的时间表达
"今天 08:30" / "昨天 18:00" / "8月10日"——"相对时间"——"用户友好"——"不显示完整时间戳"——"时间的智能"——"相对时间 vs 绝对时间"。
十、总结与展望
App 32 借还页的核心价值:用晴空蓝 + 双模式 + 虚线扫码 + 3 记录,构建一个"3 步完成借还"的工具借还页——这是共享类 App 借还页的标准范式。
与系列对比:
| App | 操作/记录类页面 | 决策 |
|---|---|---|
| 26 | 编辑器 | 写什么 |
| 27 | 日历 | 何时 |
| 28 | 衣橱 | 怎么穿 |
| 29 | 餐厅 | 吃什么 |
| 30 | 公益 | 帮什么 |
| 31 | 菜单 | 喝什么 |
| 32 | 借还 | 借/还什么 |
"32 借还页的决策是'借还是还'"——"借还页 = 操作执行"——"借还有动作方向"——"借 = 拿走、还 = 归还"——"32 帮用户完成借或还"。
终评:晴空蓝 + 双胶囊 + 虚线扫码 + 3 记录 = 完整工具借还页——"从配色到信息架构的完整设计"——"借还页的标杆"。

更多推荐





所有评论(0)