前言
卡片式布局是萌宠日记中最核心的 UI 设计模式。从首页的宠物信息卡片、今日记录卡片、健康提醒卡片,到宠物档案页的基本信息卡片、成长记录卡片,再到社区页的活动横幅卡片、帖子卡片— 整个应用中有10 余处使用了卡片式设计。
本文将从萌宠日记中所有卡片的使用出发,深入解析卡片组件的复用模式、通用样式封装、差异化配置,以及如何通过组件化设计实现“一处定义、多处复用“。
一、卡片使用全景
1.1 所有卡片清单
| 页面 | 卡片名称 | 用途 | 关键差异化 |
|---|---|---|---|
| 首页 | 宠物信息卡片 | 展示宠物头像和信息 | 头像 64×64,有编辑按钮 |
| 首页 | 今日记录卡片 | 展示日记摘要 | 有缩略图,文本截断 |
| 首页 | 健康提醒卡片 | 健康事项列表 | 列表项,有倒计时 |
| 档案页 | 头部卡片 | 宠物头像和信息 | 头像 80×80,更大 |
| 档案页 | 基本信息卡片 | 标签-值列表 | 有 Divider 分隔线 |
| 档案页 | 成长记录卡片 | 成长阶段网格 | 4 列网格布局 |
| 社区 | 活动横幅卡片 | 活动推广 | 按钮 + 文案 |
| 社区 | 帖子卡片 | 用户动态 | 头像 + 正文 + 图片 |
| 统计 | 日记数量卡片 | 统计数据 | 柱状图 + 数字 |
| 统计 | 心情分布卡片 | 饼图 + 图例 | 图表 + 百分比 |
| 统计 | 活动统计卡片 | 活动次数 | 图标 + 数字 |
1.2 卡片通用样式
// 所有卡片的通用样式 // 背景色:白色 // 圆角:16vp // 阴影:轻微 // 内边距:16vp // 统一的卡片容器 Column() { // 卡片内容 } .width('100%') .backgroundColor('#FFFFFF') .borderRadius(16) .shadow({ radius: 4, color: '#10000000', offsetY: 2 })提示:萌宠日记中所有卡片都遵循白色背景 + 16vp 圆角 + 轻微阴影的统一视觉规范。但部分卡片(如今日记录卡片、健康提醒卡片)没有使用阴影,以保持视觉层次上的区分。
二、通用卡片组件封装
2.1 基础卡片组件
// 通用卡片组件 @Component export struct Card { @Prop backgroundColor: string = '#FFFFFF' @Prop borderRadius: number = 16 @Prop paddingValue: number = 16 @Prop hasShadow: boolean = true build() { Column() { // 卡片内容通过 @BuilderParam 传入 if (this.content) { this.content() } } .width('100%') .backgroundColor(this.backgroundColor) .borderRadius(this.borderRadius) .padding(this.paddingValue) .shadow( this.hasShadow ? { radius: 4, color: '#10000000', offsetY: 2 } : undefined ) } @BuilderParam content?: () => void }2.2 使用示例
// 使用通用卡片组件 Card({ paddingValue: 16 }) { Column({ space: 12 }) { Text('基本信息').fontSize(16).fontWeight(FontWeight.Bold) // 列表内容... } }三、卡片组件参数化
3.1 参数设计
interface CardConfig { backgroundColor?: string // 背景色,默认白色 borderRadius?: number // 圆角,默认 16 paddingValue?: number // 内边距,默认 16 hasShadow?: boolean // 是否有阴影,默认 true marginValue?: Margin // 外边距 onClick?: () => void // 点击事件 }3.2 不同卡片的配置
| 卡片 | backgroundColor | borderRadius | hasShadow | paddingValue |
|---|---|---|---|---|
| 宠物信息卡片 | 白色 | 16 | true | 16 |
| 今日记录卡片 | 白色 | 12 | false | 16 |
| 健康提醒卡片 | 白色 | 12 | false | 16 |
| 活动横幅卡片 | 白色 | 16 | true | 16 |
| 统计卡片 | 白色 | 16 | true | 16 |
| 帖子卡片 | 白色 | 16 | true | 16 |
四、卡片内容的复用
4.1 标题行复用
// 卡片标题行 — 多处复用 @Builder CardTitle(title: string, action?: { label: string, onClick: () => void }) { Row() { Text(title) .fontSize(16) .fontWeight(FontWeight.Bold) .fontColor('#333333') Blank() if (action) { Text(action.label) .fontSize(14) .fontColor('#F5A623') .onClick(action.onClick) } } .width('100%') }4.2 使用示例
// 基本信息卡片 Column({ space: 12 }) { CardTitle('基本信息') // 列表内容... } // 健康提醒卡片 Column({ space: 12 }) { CardTitle('健康提醒', { label: '+', onClick: () => {} }) // 提醒列表... } // 统计卡片 Column({ space: 12 }) { CardTitle('日记数量') // 统计内容... }五、卡片内边距与外边距
5.1 边距分类
// 卡片内边距 — 内容与卡片边框的距离 .padding(16) // 卡片外边距 — 卡片与周围元素的距离 .margin({ left: 16, right: 16, bottom: 16 })5.2 边距规范
| 边距类型 | 默认值 | 说明 |
|---|---|---|
| 卡片内边距 | 16vp | 内容与卡片边框 |
| 卡片左右外边距 | 16vp | 卡片与屏幕边缘 |
| 卡片上下间距 | 16vp | 卡片之间的垂直间距 |
| 标题与内容间距 | 12vp | 卡片内标题与内容的间距 |
六、卡片阴影策略
6.1 阴影使用场景
// 有阴影的卡片 — 突出显示 .shadow({ radius: 4, color: '#10000000', offsetY: 2 }) // 宠物信息卡片、活动横幅、统计卡片、帖子卡片 // 无阴影的卡片 — 内容展示 // 今日记录卡片、健康提醒卡片6.2 阴影设计原则
| 卡片类型 | 阴影 | 设计意图 |
|---|---|---|
| 独立卡片 | 有阴影 | 从页面背景中突出 |
| 列表项卡片 | 无阴影 | 减少视觉噪点 |
| 嵌套卡片 | 无阴影 | 避免阴影叠加 |
七、卡片布局的组件化
7.1 组件拆分
CardContainer(卡片容器) ├── CardTitle(标题行) ├── CardContent(内容区) │ ├── InfoList(信息列表) │ ├── GridLayout(网格布局) │ └── ChartContent(图表内容) └── CardFooter(底部操作区)7.2 组件复用关系
// 宠物档案页 = CardContainer + CardTitle + InfoList // 统计页 = CardContainer + CardTitle + ChartContent // 社区页 = CardContainer + CardTitle + PostContent八、卡片复用收益
8.1 代码量对比
| 实现方式 | 代码量 | 维护成本 | 一致性 |
|---|---|---|---|
| 重复编写 | 每条卡片 15-20 行 | 高 | 低 |
| 组件封装 | 基础组件 30 行 + 使用 5 行 | 低 | 高 |
8.2 复用统计
| 复用维度 | 复用次数 | 说明 |
|---|---|---|
| 卡片容器样式 | 10+ 次 | 所有卡片 |
| 标题行组件 | 6+ 次 | 带标题的卡片 |
| 阴影配置 | 5+ 次 | 独立卡片 |
| 16vp 内边距 | 10+ 次 | 所有卡片 |
九、卡片性能优化
9.1 渲染性能
| 优化策略 | 说明 |
|---|---|
| 避免嵌套过深 | 卡片容器嵌套不超过 3 层 |
| 使用 @Builder 复用 | 避免重复创建组件实例 |
| 条件渲染 | 阴影等属性按需渲染 |
| 轻量组件 | 卡片内容使用轻量组件 |
9.2 卡片在列表中的性能
// 在列表中使用卡片时,使用 LazyForEach 优化 LazyForEach(this.cardData, (item: CardData) => { ListItem() { Card({ hasShadow: true }) { // 卡片内容 } } }, (item: CardData) => item.id)十、最佳实践
10.1 卡片设计原则
有序列表 — 卡片设计的 5 个原则:
- 统一视觉规范:所有卡片使用相同的背景色、圆角、阴影风格
- 组件化封装:将卡片容器封装为通用组件,减少重复代码
- 参数化配置:通过参数控制卡片样式差异(阴影、圆角、内边距)
- 内容与容器分离:卡片容器只负责样式,内容由 @BuilderParam 传入
- 差异化恰到好处:不同卡片在统一风格下保留差异化特征
10.2 萌宠日记卡片复用总结
| 卡片类型 | 容器 | 标题 | 内容 | 阴影 |
|---|---|---|---|---|
| 宠物信息卡片 | Card | 无 | 头像 + 信息 | ✅ |
| 今日记录卡片 | Card | CardTitle | 文本 + 缩略图 | ❌ |
| 健康提醒卡片 | Card | CardTitle | 列表项 | ❌ |
| 基本信息卡片 | Card | CardTitle | 标签-值列表 | ✅ |
| 成长记录卡片 | Card | CardTitle | 网格布局 | ✅ |
| 活动横幅卡片 | Card | 无 | 文案 + 按钮 | ✅ |
| 帖子卡片 | Card | 无 | 头像 + 正文 + 图片 | ✅ |
| 统计卡片 | Card | CardTitle | 图表 + 数字 | ✅ |
总结
本文从萌宠日记的卡片式布局复用出发,深入解析了卡片组件化的完整方法:
- 卡片全景:10+ 处卡片使用,覆盖所有主要页面
- 通用组件封装:Card 组件 + @BuilderParam 内容插槽
- 参数化配置:backgroundColor、borderRadius、hasShadow 等
- 标题行复用:CardTitle Builder 复用 6+ 次
- 边距规范:统一的 16vp 内边距和外边距
- 阴影策略:独立卡片有阴影,列表项无阴影
- 组件拆分:CardContainer → CardTitle → CardContent
- 复用收益:减少代码量、提升一致性、降低维护成本
卡片式布局的组件化复用,是萌宠日记保持 UI 一致性和开发效率的关键设计模式。
下一篇我们将深入宠物信息数据结构设计,解析宠物数据模型的设计与演进。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- @Component 自定义组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-create-custom-components
- @BuilderParam 装饰器:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-builderparam
- @Prop 装饰器:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-prop
- 卡片设计指南:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/design-cards
- 阴影属性:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-shadow-effect
- 组件化设计:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/component-based-design
- 布局基础:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkui-layout
- 性能优化:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/performance-optimization