文章配图: 容器的卡片化套路

页面预览

前言

主菜单的标题、按钮是「原子元素」,但一个完整界面需要把多个原子组织成卡片。在 HarmonyOS 里,Column(垂直线性容器)是最常用的卡片骨架——它把若干子元素自上而下排列,并通过 paddingbackgroundColorborderRadiusalignItems 四个属性把自身装扮成一张「浮在背景上的圆角白卡片」。

本篇以「猫猫大作战」主菜单的游戏规则面板为锚点,把 Column 容器的卡片化套路讲透。读完本篇你将能独立写出:圆角白底卡片内容左对齐卡片带阴影浮起卡片,并为后续第 5 篇的「Column 整体竖向布局」打好基础。

提示:本系列不讲 ArkTS 基础语法与环境搭建,假设你已跟完第 1–3 篇。

一、场景拆解:规则面板的卡片规格

打开 entry/src/main/ets/pages/Index.etsMainMenuView,找到规则面板:

// 来源:entry/src/main/ets/pages/Index.ets  MainMenuView()
Column() {
  Text('游戏规则')
    .fontSize(14)
    .fontWeight(FontWeight.Bold)
    .fontColor('#2C3E50')
    .margin({ bottom: 8 })
  Text('• 点击列投放猫咪')
    .fontSize(13)
    .fontColor('#7F8C8D')
    .margin({ bottom: 4 })
  Text('• 相邻同级猫咪自动合并升级')
    .fontSize(13)
    .fontColor('#7F8C8D')
    .margin({ bottom: 4 })
  Text('• 连续合并触发连击加分')
    .fontSize(13)
    .fontColor('#7F8C8D')
    .margin({ bottom: 4 })
  Text('• 猫咪堆到顶部则游戏结束')
    .fontSize(13)
    .fontColor('#7F8C8D')
}
.width('80%')
.padding(16)
.backgroundColor('rgba(255,255,255,0.7)')
.borderRadius(12)
.alignItems(HorizontalAlign.Start)

这个 Column 的卡片规格拆解:

维度 取值 作用
宽度 '80%' 占父容器 8 成,两侧留白
内边距 16 vp 内容与卡片边的呼吸空间
底色 rgba(255,255,255,0.7) 半透明白,盖在渐变蓝背景上显浮起
圆角 12 vp 比按钮圆角小,卡片更克制
子对齐 HorizontalAlign.Start 规则是阅读型内容,左对齐

关键经验:卡片圆角(12)< 按钮圆角(28),子元素左对齐而非居中,底色用半透明而非纯白——四个细节让卡片「浮」得克制不抢戏。

二、Column 容器核心属性速览

参考 线性布局 (Row/Column) 官方指南Column 是垂直线性容器,子元素自上而下排列。

2.1 本篇用到的属性清单

属性 类型 作用 本篇取值
space number 子元素之间的统一间距 未用(用 margin 单独控)
width string | number 容器宽度 '80%'
height string | number 容器高度 不设(内容撑开)
padding Padding | number 内边距 16
backgroundColor string | Color 背景色 rgba(255,255,255,0.7)
borderRadius number 圆角 12
alignItems HorizontalAlign 枚举 子元素水平对齐 Start
justifyContent FlexAlign 枚举 子元素垂直排列 未用(内容自上而下)

2.2 Column vs Row 主轴方向

容器 主轴 交叉轴 alignItems justifyContent
Column 垂直 ↓ 水平 ↔ 水平对齐 垂直排列
Row 水平 ↔ 垂直 ↓ 垂直对齐 水平排列

易错点:在 Column 里用 justifyContent(FlexAlign.Center) 是让子元素垂直居中(上下留白均分),不是水平居中。水平居中要靠 alignItems(HorizontalAlign.Center)

2.3 HorizontalAlign 三值

HorizontalAlign.Start    // 左对齐
HorizontalAlign.Center   // 居中
HorizontalAlign.End      // 右对齐

规则面板用 Start,因为规则是阅读型内容,左对齐扫读效率最高。主菜单整体用 Center,因为标题、按钮是焦点元素,居中显眼。

三、padding 内边距的两种写法

3.1 统一值(本项目写法)

.padding(16)   // 上下左右均 16vp

最简洁,适合内容对称的卡片。

3.2 分边指定

.padding({ top: 20, right: 16, bottom: 16, left: 16 })

关键经验:标题区 padding.top 常比 bottom 大(20 vs 16),因为标题上方要更多呼吸空间;按钮区反之,bottom 常比 top 大。

提示:padding 是内边距,margin 是外边距。卡片背景色会覆盖 padding 区域但不会覆盖 margin 区域。要让圆角白底卡片四周都有白底,用 padding;要让卡片与相邻元素拉距离,用 margin

四、backgroundColor 半透明的浮起感

.backgroundColor('rgba(255,255,255,0.7)')

为什么用半透明白而不是纯白?主菜单整体有浅蓝渐变背景,卡片用纯白 #FFFFFF 会显得「贴死」在上面;用 0.7 透明度的白,背景的浅蓝会从卡片下方隐隐透上来,卡片「浮」在背景上的层次感就出来了。

4.1 颜色字符串三种格式

.backgroundColor('#FFFFFF')              // 纯白,16 进制
.backgroundColor('rgba(255,255,255,0.7)') // 半透明白,rgba
.backgroundColor(Color.White)             // 系统枚举

何时用哪个

  • #RRGGBB:默认选择,最简洁。
  • rgba(r,g,b,a):需要透明度时,a 取 0–1。
  • Color.* 枚举:只用系统预定义色(Red、White、Black 等),自定义色必须用字符串。

4.2 卡片底色推荐色板

场景 推荐色 说明
浅色背景上的卡片 rgba(255,255,255,0.7) 半透明白,浮起感
深色背景上的卡片 rgba(0,0,0,0.5) 半透明黑,下沉感
信息卡片 #F8F9F9 浅灰,低调
警告卡片 rgba(231,76,60,0.1) 红色 0.1,淡红底

五、borderRadius 圆角的克制

.borderRadius(12)

卡片圆角 12vp 是主流 sweet spot。对比按钮圆角:

元素 圆角 高度 视觉
开始按钮 28 56 完美胶囊
规则卡片 12 内容撑开 小圆角矩形

关键经验:卡片圆角别超过 20,否则像「气泡」不像「卡片」。8–16 是甜区。

5.1 分角圆角

.borderRadius({ topLeft: 12, topRight: 12, bottomLeft: 0, bottomRight: 0 })

只圆顶部两角,底部方角——适合「底部紧贴导航栏」的卡片。本项目没用,但实战中常见。

六、alignItems 子对齐的视觉语义

.alignItems(HorizontalAlign.Start)

三种对齐对应三种视觉语义:

对齐 语义 适用
Start 阅读型,扫读效率高 规则、说明、列表项
Center 焦点型,显眼 标题、按钮、图标
End 数字型,对齐数字 价格、得分、统计

规则面板用 Start,因为 5 行规则是阅读型内容。如果误用 Center,每行长度不一,居中后视觉错乱。

七、完整代码:三种卡片样式对比

7.1 规则卡片(本项目当前写法)

Column() {
  Text('游戏规则')
    .fontSize(14)
    .fontWeight(FontWeight.Bold)
    .fontColor('#2C3E50')
    .margin({ bottom: 8 })
  Text('• 点击列投放猫咪')
    .fontSize(13)
    .fontColor('#7F8C8D')
    .margin({ bottom: 4 })
  // ... 其余 3 条规则
}
.width('80%')
.padding(16)
.backgroundColor('rgba(255,255,255,0.7)')
.borderRadius(12)
.alignItems(HorizontalAlign.Start)

7.2 统计卡片(带阴影浮起)

Column() {
  Text('本局统计')
    .fontSize(14)
    .fontWeight(FontWeight.Bold)
    .fontColor('#2C3E50')
    .margin({ bottom: 12 })
  Row() {
    Text('得分').fontSize(12).fontColor('#7F8C8D').layoutWeight(1)
    Text('最高分').fontSize(12).fontColor('#7F8C8D').layoutWeight(1)
    Text('用时').fontSize(12).fontColor('#7F8C8D').layoutWeight(1)
  }.margin({ bottom: 8 })
  Row() {
    Text(`${this.score}`).fontSize(20).fontColor('#2ECC71').layoutWeight(1)
    Text(`${this.highScore}`).fontSize(20).fontColor('#2ECC71').layoutWeight(1)
    Text(`${this.formatTime()}`).fontSize(20).fontColor('#2ECC71').layoutWeight(1)
  }
}
.width('80%')
.padding(16)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.shadow({ radius: 8, color: 'rgba(0,0,0,0.1)', offsetY: 2 })
.alignItems(HorizontalAlign.Start)

统计卡片 vs 规则卡片差异:

  • 底色:纯白 #FFFFFF(统计要清晰)vs 半透明白(规则要低调)
  • 阴影:有 shadow(浮起显重要)vs 无(融入背景)
  • 内部:用 Row 横排三列数据 vs 纯 Text 竖排

7.3 警告卡片(淡红底)

Column() {
  Text('⚠ 注意')
    .fontSize(14)
    .fontWeight(FontWeight.Bold)
    .fontColor('#E74C3C')
    .margin({ bottom: 8 })
  Text('猫咪堆到第 2 行即游戏结束,请及时合并。')
    .fontSize(13)
    .fontColor('#7F8C8D')
}
.width('80%')
.padding(16)
.backgroundColor('rgba(231,76,60,0.1)')
.borderRadius(12)
.alignItems(HorizontalAlign.Start)

警告卡片用淡红底 rgba(231,76,60,0.1) + 红字标题,视觉语义明确。

八、调试技巧:卡片怎么量尺寸

  1. 临时加 border.border({ width: 1, color: Color.Red }) 看清卡片占框,调完去掉。
  2. width 用百分比:响应式,但父容器宽度要先确定。本项目主菜单 Column 是 100% 屏宽,规则卡片 80% 即 8 成屏宽。
  3. height 不设:让内容撑开高度,避免内容多了被裁。
  4. 预览器看圆角:DevEco 预览器圆角渲染接近真机,可放心调。

九、性能与最佳实践

  1. padding 别小于 12:内容贴边显得拥挤,16 是甜区。
  2. borderRadius 别超过 20:卡片不是气泡,8–16 是甜区。
  3. 半透明底色注意可读性rgba(255,255,255,0.7) 透 0.3 背景色,如果背景太花,卡片内文字可能不清。实测不清就把 0.7 调到 0.85 或纯白。
  4. alignItems 与子元素 width 协同:卡片 alignItems(Start) 时,子 Text 默认宽度是内容宽度;想让规则行铺满卡片宽度,给子 Text.width('100%')

总结

本篇我们从规则面板切入,掌握 Column 容器的 paddingbackgroundColorborderRadiusalignItems 四大卡片化属性,并给出了规则、统计、警告三种视觉语义的完整代码。核心要点:圆角 12 比 28 克制,半透明白底浮起感,左对齐是阅读型,纯白+阴影是焦点型

下一篇我们将继续主菜单,拆解整体竖向布局的 Column + Spacer 占位,把 spacejustifyContentSpacer/Blank 间距控制讲透。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

更多推荐