鸿蒙学习实战之路-弹性布局 Flex 全攻略
鸿蒙学习实战之路-弹性布局 Flex 全攻略
最近好多朋友问我:"我想在鸿蒙里做个漂亮的页面布局,但 Row 和 Column 太死板了,有没有更灵活的方式?"_
今天这篇,我就手把手带你搞定弹性布局(Flex)——鸿蒙里最灵活的布局神器!全程都是能跑的代码和避坑指南,看完你就能轻松实现各种复杂布局~ o(∩_∩)o
一、什么是弹性布局?
弹性布局(Flex)就像一个会伸缩的容器,能自动帮你调整里面元素的位置和大小。想象一下,你有一个弹性口袋,不管里面装多少东西,它都能自动分配空间,让东西摆得整整齐齐~
核心概念:
- 主轴:元素排列的方向(水平/垂直)
- 交叉轴:垂直于主轴的方向
这两个轴是理解 Flex 的关键,咱们先记住它们~
二、快速上手:写一个简单的 Flex 布局
咱们先写一个最基础的弹性布局,感受一下它的威力!
@Entry
@Component
struct FlexBasicExample {
build() {
Column() {
// 创建一个水平方向的Flex容器
Flex() {
Text('我是第一个元素').width('33%').height(50).backgroundColor('#F5DEB3')
Text('我是第二个元素').width('33%').height(50).backgroundColor('#D2B48C')
Text('我是第三个元素').width('33%').height(50).backgroundColor('#F5DEB3')
}
.height(70)
.width('90%')
.padding(10)
.backgroundColor('#AFEEEE')
}
.width('100%')
.height('100%')
}
}
效果:三个元素会自动在水平方向上排列,每个占容器宽度的 33%~

🥦 西兰花小贴士:
Flex 默认是水平方向(Row)排列的,这也是最常用的布局方式~
三、布局方向:灵活控制元素排列
刚才咱们用的是默认的水平方向,其实 Flex 支持四种布局方向:
1. 水平方向(默认)
Flex({ direction: FlexDirection.Row }) {
// 元素内容
}
2. 水平反向
Flex({ direction: FlexDirection.RowReverse }) {
Text('1').width('33%').height(50).backgroundColor('#F5DEB3')
Text('2').width('33%').height(50).backgroundColor('#D2B48C')
Text('3').width('33%').height(50).backgroundColor('#F5DEB3')
}
效果:元素从右往左排列~

3. 垂直方向
Flex({ direction: FlexDirection.Column }) {
// 元素内容
}
4. 垂直反向
Flex({ direction: FlexDirection.ColumnReverse }) {
// 元素内容
}
🥦 西兰花警告:
方向设置会影响主轴和交叉轴的方向哦!比如垂直方向时,主轴变成了垂直方向,交叉轴变成了水平方向~
四、布局换行:处理元素太多的情况
如果元素总宽度超过了容器宽度,Flex 默认会压缩元素。但咱们可以设置换行,让元素自动换行排列~
1. 不换行(默认)
Flex({ wrap: FlexWrap.NoWrap }) {
Text('1').width('50%').height(50).backgroundColor('#F5DEB3')
Text('2').width('50%').height(50).backgroundColor('#D2B48C')
Text('3').width('50%').height(50).backgroundColor('#F5DEB3')
}
效果:三个元素都被压缩在一行里~

2. 换行
Flex({ wrap: FlexWrap.Wrap }) {
Text('1').width('50%').height(50).backgroundColor('#F5DEB3')
Text('2').width('50%').height(50).backgroundColor('#D2B48C')
Text('3').width('50%').height(50).backgroundColor('#D2B48C')
}
效果:第三个元素自动换到了下一行~

3. 反向换行
Flex({ wrap: FlexWrap.WrapReverse }) {
// 元素内容
}
五、主轴对齐:控制元素在主轴上的位置
主轴对齐是 Flex 最常用的功能之一,它能控制元素在主轴方向上的排列方式。咱们来看看常用的几种:
1. 起始对齐(默认)
Flex({ justifyContent: FlexAlign.Start }) {
Text('1').width('20%').height(50).backgroundColor('#F5DEB3')
Text('2').width('20%').height(50).backgroundColor('#D2B48C')
Text('3').width('20%').height(50).backgroundColor('#F5DEB3')
}
效果:元素从主轴起始端排列~

2. 居中对齐
Flex({ justifyContent: FlexAlign.Center }) {
// 元素内容
}
效果:元素在主轴方向居中~

3. 末尾对齐
Flex({ justifyContent: FlexAlign.End }) {
// 元素内容
}
4. 均匀分布
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
// 元素内容
}
效果:元素之间距离相等,两端贴边~

5. 环绕分布
Flex({ justifyContent: FlexAlign.SpaceAround }) {
// 元素内容
}
效果:元素之间距离相等,两端距离是中间的一半~
6. 等间距分布
Flex({ justifyContent: FlexAlign.SpaceEvenly }) {
// 元素内容
}
效果:所有间距都相等~
六、交叉轴对齐:控制元素在交叉轴上的位置
交叉轴对齐控制元素在垂直于主轴方向上的排列。Flex 容器和子元素都可以设置交叉轴对齐~
1. 容器设置交叉轴对齐
Flex({ alignItems: ItemAlign.Center }) {
Text('1').width('33%').height(30).backgroundColor('#F5DEB3')
Text('2').width('33%').height(40).backgroundColor('#D2B48C')
Text('3').width('33%').height(50).backgroundColor('#F5DEB3')
}
.size({ width: '90%', height: 80 })
效果:不同高度的元素在交叉轴上居中对齐~

常用的交叉轴对齐方式:
ItemAlign.Start:交叉轴起始端对齐ItemAlign.Center:交叉轴居中对齐ItemAlign.End:交叉轴末尾对齐ItemAlign.Stretch:拉伸填充交叉轴ItemAlign.Baseline:文本基线对齐
2. 子元素单独设置交叉轴对齐
咱们还可以给某个子元素单独设置交叉轴对齐,覆盖容器的设置~
Flex() {
Text('1').width('33%').height(30).backgroundColor('#F5DEB3')
.alignSelf(ItemAlign.End) // 单独设置这个元素在交叉轴末尾对齐
Text('2').width('33%').height(40).backgroundColor('#D2B48C')
Text('3').width('33%').height(50).backgroundColor('#F5DEB3')
}
🥦 西兰花小贴士:
alignSelf 是子元素的属性,可以单独控制某个元素的交叉轴对齐方式~
七、实战案例:实现一个导航栏
咱们来做个实战案例——实现一个手机应用常见的导航栏布局~
@Entry
@Component
struct FlexNavBarExample {
build() {
Column() {
// 导航栏容器
Flex() {
// 左侧返回按钮
Text('←').fontSize(24)
.width(40).height(40)
.textAlign(TextAlign.Center)
.alignSelf(ItemAlign.Center)
// 标题(自动占满剩余空间)
Text('弹性布局教程')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.flexGrow(1) // 自动占满剩余空间
.textAlign(TextAlign.Center)
// 右侧更多按钮
Text('⋮').fontSize(24)
.width(40).height(40)
.textAlign(TextAlign.Center)
.alignSelf(ItemAlign.Center)
}
.width('100%')
.height(56)
.padding({ left: 16, right: 16 })
.backgroundColor('#FFFFFF')
.borderBottom({ width: 1, color: '#E5E5E5' })
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
}
解析:
- 使用
flexGrow(1)让标题自动占满剩余空间 - 使用
alignSelf让按钮垂直居中 - 整体实现了一个常见的导航栏布局~
🥦 西兰花警告:
flexGrow 属性非常好用,它能让元素自动分配剩余空间。但要注意,只有在主轴有剩余空间时才会生效哦!
八、高级技巧:Flex 的更多用法
1. 自适应拉伸
使用 flexGrow 可以让元素自动分配剩余空间,实现自适应布局~
Flex() {
Text('固定宽度').width(100).height(50).backgroundColor('#F5DEB3')
Text('自适应宽度').height(50).backgroundColor('#D2B48C')
.flexGrow(1) // 占满剩余空间
Text('固定宽度').width(100).height(50).backgroundColor('#F5DEB3')
}
2. 嵌套 Flex
咱们可以在 Flex 容器里再放 Flex 容器,实现更复杂的布局~
Flex({ direction: FlexDirection.Column }) {
// 顶部栏
Flex() {
// 顶部栏内容
}
// 中间内容区
Flex() {
// 中间内容
}
.flexGrow(1) // 占满剩余空间
// 底部栏
Flex() {
// 底部栏内容
}
}
九、避坑指南
1. 方向设置影响轴的方向
- 水平方向:主轴是水平,交叉轴是垂直
- 垂直方向:主轴是垂直,交叉轴是水平
2. 对齐方式的优先级
- 子元素的
alignSelf优先级高于容器的alignItems - 主轴对齐和交叉轴对齐是独立的,需要分别设置
3. 换行和不换行的区别
NoWrap:元素会被压缩Wrap:元素会自动换行
4. flexGrow 的使用场景
- 只有在主轴有剩余空间时才会生效
- 可以同时给多个元素设置,按比例分配空间
十、额外案例:实现一个商品卡片
咱们来实现一个电商应用中常见的商品卡片布局,只使用色块和 Flex 布局~
@Entry
@Component
struct FlexProductCardExample {
build() {
Column() {
Text('商品卡片示例')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin(20)
// 商品卡片容器
Flex({ direction: FlexDirection.Column }) {
// 商品图片区域(色块模拟)
Stack() {
Text('商品图片')
.fontSize(16)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
}
.width('100%')
.height(200)
.backgroundColor('#D2B48C')
// 商品信息区域
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
// 商品标题
Text('这是一个非常好用的商品')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin(8)
// 商品描述
Text('这个商品真的很不错,买了不会后悔的~')
.fontSize(14)
.fontColor('#666666')
.margin(12)
// 价格和购买按钮区域
Flex() {
// 价格
Text('¥99.99')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#FF4444')
.flexGrow(1)
// 购买按钮
Text('立即购买')
.width(100)
.height(36)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor('#FF4444')
.borderRadius(18)
}
}
}
.width('90%')
.backgroundColor(Color.White)
.borderRadius(12)
.shadow({
radius: 4,
color: '#00000020',
offsetX: 0,
offsetY: 2
})
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
}
代码解析:
- 整体使用垂直方向的 Flex 容器作为卡片主体
- 顶部用 Stack 和色块模拟商品图片区域
- 中间使用垂直 Flex 容器存放商品信息
- 底部使用水平 Flex 容器实现价格和购买按钮的布局,价格区域用
flexGrow(1)自动占满剩余空间 - 最后添加圆角和阴影效果,让卡片更立体
这个案例展示了如何用 Flex 布局实现一个常见的商品卡片,代码简单易懂,只使用了色块和文本,没有依赖图片~
🥦 西兰花小贴士:
商品卡片是电商应用的核心组件,掌握这个布局可以举一反三,实现更多类似的卡片式设计~
写在最后
恭喜你!现在你已经掌握了弹性布局(Flex)的核心用法~ 这是鸿蒙开发中最灵活的布局方式,几乎能满足所有的布局需求~
下一步学习建议:
- 尝试用 Flex 实现一个完整的页面布局
- 结合其他组件(如 Scroll、Swiper)使用 Flex
- 探索 Flex 的更多高级属性
📚 推荐资料:
我是盐焗西兰花,
不教理论,只给你能跑的代码和避坑指南。
下期见!🥦

浙公网安备 33010602011771号