【HarmonyOS 6】“记录“页面的UI布局拆解
前面我们拆了"维系"和"档案"两个页面。这篇来看第三个 Tab——记录。
"维系"页是混合拼图,"档案"页是单一卡片重复,而"记录"页介于两者之间:有一个筛选栏 + 同一种卡片的纵向列表。但它的卡片内部结构是三个页面中最复杂的——左侧图标、右侧双行信息、底部详情文字,三段式布局。
一、页面全貌

代码骨架:
@Builder
InteractionTab() {
Scroll() {
Column() {
Row() { Text('互动记录') Blank() Text('+ 记录') }
Text('礼物、宴请、帮助、关怀都值得被记住')
Row() { 筛选药丸 × 5 }
ForEach(this.records, (item: InteractionRecord) => {
this.InteractionRecordCard(item)
}, ...)
}
.width('100%')
.padding({ left: 24, right: 24, top: 0, bottom: 140 })
}
.scrollBar(BarState.Off)
.height('100%')
.width('100%')
.backgroundColor('#F9F7F2')
}
外层结构和前两个页面完全一致,不再重复。这篇重点讲三个东西:标题行的操作入口、筛选栏、记录卡片。
二、标题行:和"档案"页如出一辙
Row() {
Text('互动记录')
.fontSize(26)
.fontWeight(FontWeight.Bold)
.fontColor('#2C2723')
Blank()
Text('+ 记录')
.fontSize(15)
.fontColor('#8B7355')
}
.width('100%')
.alignItems(VerticalAlign.Center)
.margin({ top: 20, bottom: 6 })
.padding({ left: 2, right: 2 })
和"档案"页的标题行结构完全相同:Row + Blank() + 右侧操作文字。alignItems(VerticalAlign.Center) 让大小号文字垂直居中。
2.1 "+ 记录"目前是纯文本
当前右侧的 + 记录 只是一个 Text,品牌色 #8B7355,没有背景、没有圆角、没有点击态。它视觉上能被识别为可操作元素,全靠颜色和 + 符号的暗示。
三、筛选栏:水平排列的“药丸”
Row() {
this.InteractionFilterPill('全部', true)
this.InteractionFilterPill('礼物往来', false)
this.InteractionFilterPill('宴请聚会', false)
this.InteractionFilterPill('帮助支持', false)
this.InteractionFilterPill('日常关怀', false)
}
.width('100%')
.margin({ bottom: 18 })
5 个筛选药丸水平排列在一个 Row 里。
3.1 药丸组件
@Builder
InteractionFilterPill(text: string, selected: boolean) {
Text(text)
.fontSize(13)
.fontWeight(selected ? FontWeight.Medium : FontWeight.Normal)
.fontColor(selected ? '#FFFFFF' : '#8A8076')
.padding({ left: 14, right: 14, top: 8, bottom: 8 })
.borderRadius(16)
.backgroundColor(selected ? '#3D3632' : '#FFFFFF')
.margin({ right: 10 })
}
选中态和未选中态的对比:
| 状态 | 字色 | 背景 | 字重 |
|---|---|---|---|
| 选中 | #FFFFFF 白 |
#3D3632 深棕 |
Medium |
| 未选中 | #8A8076 灰 |
#FFFFFF 白 |
Normal |
深底白字 vs 白底灰字,对比非常强烈,用户一眼就能看出当前选中的是哪个。
3.2 为什么不用 Scroll 包裹
5 个药丸在窄屏上可能超出宽度。当前代码没有用 Scroll 包裹筛选栏,而是直接放在 Row 里。
如果后续筛选项增多,可以改成:
Scroll() {
Row() {
this.InteractionFilterPill('全部', true)
this.InteractionFilterPill('礼物往来', false)
// ...
}
}
.scrollable(ScrollDirection.Horizontal)
.scrollBar(BarState.Off)
和"维系"页的横向提醒卡片同理——水平内容超出时,加一层横向 Scroll 即可。
3.3 margin({ right: 10 })
.margin({ right: 10 })
药丸之间靠 right: 10 分隔。只设右边距不设左边距,第一个药丸左边不需要间距,最后一个右边距会被父容器的 padding 吸收。
四、InteractionRecordCard:三段式卡片
这是"记录"页的核心组件。每张卡片分三段:图标行、标题行、详情文字。

@Builder
InteractionRecordCard(item: InteractionRecord) {
Column() {
// 图标 + 标题行
Row() {
Column() { ... } // 左侧图标
Column() { ... } // 右侧信息
.layoutWeight(1)
.margin({ left: 14 })
}
.width('100%')
// 详情文字
Text(item.detail)
.fontSize(14)
.lineHeight(21)
.fontColor('#8A8076')
.width('100%')
.margin({ top: 14 })
}
.alignItems(HorizontalAlign.Start)
.padding(20)
.borderRadius(20)
.backgroundColor('#FFFFFF')
.shadow({ radius: 12, color: '#1A000006', offsetY: 3 })
.margin({ bottom: 12 })
}
接下来逐层拆开。
五、左侧图标:44×44 圆角方块
Column() {
Text(item.title === '送出礼物' ? '↗' : item.title === '收到帮助' ? '↓' : '♡')
.fontSize(18)
.fontColor(item.title === '送出礼物' ? '#C4956A' : item.title === '收到帮助' ? '#7A9B8E' : '#B8929E')
}
.width(44)
.height(44)
.borderRadius(14)
.justifyContent(FlexAlign.Center)
.backgroundColor('#FAF7F2')
5.1 不是圆形,是圆角方块
.borderRadius(14)
44vp 的宽高配 14vp 的圆角,形成的是圆角方块,不是正圆。这和"档案"页的 56×56 正圆头像(borderRadius 28)形成区分——图标是功能性的,用方块;头像是身份性的,用圆形。
5.2 图标和颜色随类型变化
| 类型 | 图标 | 图标色 | 含义 |
|---|---|---|---|
| 送出礼物 | ↗ |
#C4956A 金棕 |
向外给出 |
| 收到帮助 | ↓ |
#7A9B8E 绿 |
向内收到 |
| 日常关怀 | ♡ |
#B8929E 粉 |
温情连接 |
三种类型三种颜色,用户扫一眼左侧图标就能区分记录的性质。
5.3 浅底背景
.backgroundColor('#FAF7F2')
#FAF7F2 比卡片背景 #FFFFFF 略暖,比页面背景 #F9F7F2 略白。这个微妙的色差让图标区域从卡片中"浮"出来,但不会太突兀。
六、右侧信息:双行布局
右侧是一个 Column,包含两行:
Column() {
// 第一行:标题 + 金额
Row() {
Text(item.title)
.fontSize(17)
.fontWeight(FontWeight.Bold)
.fontColor('#2C2723')
.layoutWeight(1)
// 金额或"低成本"标签
}
// 第二行:对象 + 日期
Text(`${item.target} · ${item.date}`)
.fontSize(13)
.fontColor('#B5ADA2')
.margin({ top: 5 })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
.margin({ left: 14 })
6.1 第一行的两种结尾
第一行右侧根据是否有金额,展示两种不同内容:
有金额时:
if (item.amount.length > 0) {
Text(item.amount)
.fontSize(15)
.fontWeight(FontWeight.Medium)
.fontColor('#8B7355')
}
金额用品牌色 #8B7355,15 号字 Medium 字重,比标题稍小但足够醒目。
无金额时:
else {
Text('低成本')
.fontSize(12)
.fontColor('#A0988C')
.padding({ left: 8, right: 8, top: 3, bottom: 3 })
.borderRadius(8)
.backgroundColor('#F5F0EA')
}
"低成本"做成一个小标签——12 号字、浅底 #F5F0EA、8vp 圆角。和"档案"页的特征标签风格一致,但尺寸更小,因为它是补充信息而不是核心信息。
6.2 标题用 layoutWeight(1)
Text(item.title)
.layoutWeight(1)
标题占据剩余宽度,金额/标签靠右。如果标题很长,会被截断而不是把金额挤出去。
6.3 第二行:中圆点分隔
Text(`${item.target} · ${item.date}`)
和"档案"页的亲密度行一样,用 · 分隔两个字段。#B5ADA2 浅灰色,视觉上退到第二层。
七、详情文字
Text(item.detail)
.fontSize(14)
.lineHeight(21)
.fontColor('#8A8076')
.width('100%')
.margin({ top: 14 })
详情文字和图标行之间用 margin({ top: 14 }) 分隔。没有用 Divider,因为卡片内容不多,留白比分隔线更轻盈。
lineHeight(21) 配合 fontSize(14),行间距约 7vp,阅读舒适。
八、卡片外壳
.alignItems(HorizontalAlign.Start)
.padding(20)
.borderRadius(20)
.backgroundColor('#FFFFFF')
.shadow({ radius: 12, color: '#1A000006', offsetY: 3 })
.margin({ bottom: 12 })
| 属性 | 值 | 和"档案"页对比 |
|---|---|---|
| padding | 20 | 22(记录页稍小) |
| borderRadius | 20 | 22(记录页稍小) |
| shadow radius | 12 | 14(记录页稍轻) |
记录卡片比档案卡片略小略轻,因为记录列表通常条目更多,卡片太大会让页面显得空旷。
九、总结
这篇我们拆解了"记录"页面的 UI 布局,核心要点:
- 筛选栏:深底/白底药丸切换,选中态对比强烈,后续可加横向 Scroll 适配窄屏。
- 三段式卡片:图标行 + 标题行 + 详情文字,信息层次清晰。
- 左侧图标:44×44 圆角方块(非圆形),图标和颜色随类型变化。
- 标题行双结尾:有金额显示数字,无金额显示"低成本"标签,用
layoutWeight(1)保证标题不挤压金额。 - "+ 记录"纯文本:当前靠颜色暗示可点击,后续可加背景做成药丸按钮或轻量按钮。
- 卡片尺寸介于提醒和档案之间:padding 20、borderRadius 20,比小卡片大、比大卡片小,适配列表条目较多的场景。
更多推荐


所有评论(0)