
常见布局Row和Column
Column
Column 是鸿蒙(HarmonyOS)ArkUI 框架中最基础且常用的布局容器之一,用于在垂直方向(主轴为纵轴) 上排列子组件。其行为类似于 Android 中的 LinearLayout(orientation=vertical) 或 Web 开发中的 flex-direction: column。
它适用于构建列表项、表单、卡片式布局等需要纵向堆叠内容的场景。通过灵活配置其属性,开发者可以精确控制子组件的位置、间距与对齐方式。
通用属性
width
width 用于设置 Column 容器自身的宽度。支持多种单位(如 vp、px、百分比 %),也支持使用 Length 类型的常量(如 100% 表示占满父容器宽度)。
ts
Column() {
// 子组件
}
.width('100%') // 占满父容器宽度
💡 提示:若未显式设置宽度,默认会根据子组件的最大宽度自适应。


height
height 控制 Column 的高度,用法与 width 类似。常用于限制容器高度或实现滚动区域(配合 Scroll 组件)。
ts
Column() { /* ... */ }
.height(200) // 固定高度 200vp

border
边框通过 border 属性设置,其参数类型为 BorderOptions 接口,包含多个可选字段:
width:边框粗细;color:边框颜色;radius:圆角半径(可实现圆角矩形);style:边框样式(如实线、虚线等,部分版本支持)。
ts
.border({
width: 2,
color: '#FF0000',
radius: 10
})
🔍 源码视角 :
BorderOptions是一个接口,意味着你可以只传入需要的属性,其余使用默认值。




padding
padding 设置容器内部边距 ,即子组件与容器边框之间的距离。注意:它影响的是内容区到边框的距离,而非子组件之间的间距。
ts
.padding(10) // 四周内边距均为 10vp
.padding({ left: 5, right: 15 }) // 精确控制各方向
📌 关键区别 :
padding是"内边距",margin是"外边距"。


margin
margin 控制当前 Column 与其外部兄弟组件或父容器之间的距离,属于"外边距"。
ts
.margin(20) // 外边距 20vp
⚠️ 注意 :
margin不会影响子组件之间的间距,仅作用于当前容器整体。

space
当需要统一设置所有子组件之间的垂直间距 时,使用 space 属性比逐个设置 margin 更高效、更清晰。
ts
Column({ space: 10 }) { // 所有子组件之间间隔 10vp
Text('Item 1')
Text('Item 2')
Text('Item 3')
}
✅ 最佳实践 :优先使用
space而非为每个子项加margin,代码更简洁且语义明确。

alignItems
alignItems 控制子组件在交叉轴(水平方向) 上的对齐方式。由于 Column 的主轴是垂直的,因此交叉轴为水平方向。
可选值来自 HorizontalAlign 枚举:
HorizontalAlign.Start
子组件左对齐(从左开始)。

HorizontalAlign.Center
子组件水平居中。

HorizontalAlign.End
子组件右对齐(靠右结束)。

🧭 记忆技巧 :
Column→ 垂直排列 →alignItems控制左右对齐 → 使用HorizontalAlign。


justifyContent
justifyContent 控制子组件在主轴(垂直方向) 上的分布方式。默认值为 FlexAlign.Start(顶部对齐)。
可选值包括:
FlexAlign.Start
顶部对齐(默认)。

FlexAlign.Center
垂直居中。

FlexAlign.End
底部对齐。

FlexAlign.SpaceBetween
首尾元素贴边,中间均匀分布。

FlexAlign.SpaceAround
每个元素上下间距相等,首尾留一半间距。

FlexAlign.SpaceEvenly
所有间距(包括顶部和底部)完全相等。

🎯 应用场景:
SpaceBetween:常用于页脚按钮("取消"在左,"确定"在右);Center:用于居中弹窗内容;SpaceEvenly:用于均匀分布导航图标。


单位问题
在 HarmonyOS 开发中,合理选择尺寸单位对适配多设备至关重要。
px(像素)
- 定义:物理像素单位,1px = 1 个屏幕像素点。
- 特点 :不随屏幕密度缩放,在高 DPI 设备上显示更小。
- 适用场景 :需要绝对精确的场景,如 1px 分割线、细边框。
❌ 风险:在不同设备上视觉大小不一致,可能导致 UI 错位。
vp(虚拟像素)
- 定义 :鸿蒙推荐的逻辑像素单位,系统会根据设备 DPI 自动换算为实际 px。
- 换算:1vp = 1px @ 160 DPI;在 320 DPI 设备上,1vp = 2px。
- 特点 :保证视觉一致性,相同 vp 值在不同设备上看起来大小相近。
- 适用场景 :绝大多数 UI 元素,如字体、按钮、间距、容器尺寸等。
如何选择?
| 场景 | 推荐单位 |
|---|---|
| 文字大小、按钮、容器宽高、间距 | ✅ vp |
| 1px 分割线、极细边框 | ✅ px |
| 设计稿标注(通常基于 vp) | ✅ 直接使用 vp |
注意事项
- 设计师提供的 HarmonyOS 设计稿通常以 vp 为单位,开发时应直接使用;
- 避免混用
px和vp,除非有明确需求; - 使用
px时,可通过px2vp()工具函数进行转换(如有需要)。
Row
Row 是 Column 的"水平兄弟",用于在水平方向(主轴为横轴) 上排列子组件。它同样基于 Flex 布局模型,默认从左到右排列。
🔄 核心区别 :
Column主轴为垂直,Row主轴为水平。因此,两者的对齐属性所作用的方向互换。
对比效果:
Column(垂直排列)

Row(水平排列)

💡 代码复用提示 :同一套子组件,仅需将
Column替换为Row,即可实现横向布局,极大提升开发效率。
alignItems
在 Row 中,由于主轴是水平的,交叉轴变为垂直方向 ,因此 alignItems 使用 VerticalAlign 枚举:
VerticalAlign.Top
子组件顶部对齐。

VerticalAlign.Center
垂直居中对齐。

VerticalAlign.Bottom
底部对齐。

🧭 记忆技巧 :
Row→ 水平排列 →alignItems控制上下对齐 → 使用VerticalAlign。
justifyContent
justifyContent 在 Row 中控制水平方向(主轴) 的分布,其取值与 Column 完全相同(仍为 FlexAlign 枚举),只是作用方向变为左右。
Start:左对齐(默认)Center:水平居中End:右对齐SpaceBetween/SpaceAround/SpaceEvenly:水平间距分布
✅ 无需重复学习 :只要理解主轴方向,
justifyContent的行为逻辑完全一致。

总结建议
| 布局 | 主轴方向 | alignItems 方向 | justifyContent 方向 |
|---|---|---|---|
Column |
垂直 ↓ | 水平(HorizontalAlign) |
垂直(FlexAlign) |
Row |
水平 → | 垂直(VerticalAlign) |
水平(FlexAlign) |
🏗️ 开发口诀:
- "Column 看左右,Row 看上下 " ------ 指
alignItems;- "主轴用 justifyContent,交叉轴用 alignItems"。
掌握 Row 与 Column 的异同,是构建鸿蒙应用 UI 的第一步。结合 space、padding、margin 和对齐属性,几乎可以实现所有常见的线性布局需求。
全套代码
javascript
@Entry
@Component
struct Index {
build() {
/*
Column({space:10}){
Text('你好,VON')
.width(100)
.height(100)
.border({width:1,color:'red',radius:50})
Text('你好,VON')
.width(100)
.height(100)
.border({width:1,color:'red',radius:50})
Text('你好,VON')
.width(100)
.height(100)
.border({width:1,color:'red',radius:50})
}
.width('100%')
.height('100%')
.border({width:1,color:'green',radius:50})
.alignItems(HorizontalAlign.End)
.justifyContent(FlexAlign.SpaceEvenly)
* */
Row({space:10}){
Text('你好,VON')
.width(100)
.height(100)
.border({width:1,color:'red',radius:50})
Text('你好,VON')
.width(100)
.height(100)
.border({width:1,color:'red',radius:50})
Text('你好,VON')
.width(100)
.height(100)
.border({width:1,color:'red',radius:50})
}
.width('100%')
.height('100%')
.border({width:1,color:'green',radius:50})
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.)
}
}