【HarmonyOS UI】布局必学:Row/Column/Flex 三大布局用法+实战代码+复杂场景适配
本文详细介绍了鸿蒙UI开发的三大核心布局:Row(水平布局)、Column(垂直布局)和Flex(弹性布局)。通过对比分析三种布局的特点和适用场景,重点讲解了通用属性和专属属性的使用方法。文章提供了一个完整的实战案例,展示如何将三大布局结合使用来实现导航栏、表单、标签流等常见页面模块,并附带了可直接运行的代码示例。此外,还分享了多终端适配技巧和常见问题解决方案,帮助开发者应对复杂场景。掌握这三种布
大家好,在上一篇博客中,我们学会了如何创建第一个鸿蒙应用,了解了基础的组件和布局。今天我们重点讲解鸿蒙UI开发中最核心的三大布局:Row(水平布局)、Column(垂直布局)、Flex(弹性布局)。这三大布局几乎覆盖了鸿蒙应用90%以上的页面结构,无论是简单的文本展示,还是复杂的表单、列表、导航栏,都离不开它们。
鸿蒙的布局体系基于弹性布局思想,语法简洁、适配性强,支持多终端屏幕适配(手机、平板、智慧屏),本篇将从基础用法、属性详解、实战案例、复杂场景适配四个方面,带大家彻底掌握这三大布局,附带可直接运行的完整代码,新手也能轻松上手。
一、三大布局核心概念与区别(新手必懂)
在开始编写代码之前,我们先明确三大布局的核心作用和适用场景,避免混淆,后续开发中能快速选择合适的布局。
|
布局类型 |
核心作用 |
主轴方向 |
适用场景 |
|---|---|---|---|
|
Column |
垂直布局,组件从上到下排列 |
垂直方向(从上到下) |
表单、列表、页面整体布局、垂直排列的组件组 |
|
Row |
水平布局,组件从左到右排列 |
水平方向(从左到右) |
导航栏、按钮组、搜索框、水平排列的组件组 |
|
Flex |
弹性布局,组件自适应排列,支持换行 |
可自定义(默认水平) |
商品流、标签流、自适应卡片、多终端适配布局 |
二、三大布局基础属性详解(重点)
三大布局有很多通用属性,也有各自的专属属性,掌握这些属性,就能灵活控制组件的排列方式和位置,以下是最常用的属性,附带说明和使用示例。
1. 通用属性(Row/Column/Flex都可用)
-
space:组件之间的间距,单位为vp,用于控制布局内部组件的间距,示例:Column({ space: 10 }) → 组件之间间距为10vp。
-
width/height:布局的宽和高,支持百分比(如width: '100%')、固定值(如width: 300),示例:width('90%') → 布局宽度为屏幕的90%。
-
justifyContent:主轴对齐方式,控制组件在主轴方向上的排列位置,常用值:
-
FlexAlign.Start:主轴起始位置对齐(默认)。
-
FlexAlign.Center:主轴居中对齐。
-
FlexAlign.End:主轴结束位置对齐。
-
FlexAlign.SpaceBetween:组件两端对齐,中间间距均分。
-
FlexAlign.SpaceAround:组件之间间距均分,两端留白。
-
-
alignItems:交叉轴对齐方式,控制组件在交叉轴方向上的排列位置,常用值:
-
ItemAlign.Start:交叉轴起始位置对齐。
-
ItemAlign.Center:交叉轴居中对齐(默认)。
-
ItemAlign.End:交叉轴结束位置对齐。
-
-
backgroundColor:布局的背景色,支持十六进制、RGB等格式,示例:backgroundColor('#f5f5f5')。
-
padding:布局的内边距,控制布局内部组件与布局边界的距离,示例:padding(15) → 四个方向内边距都是15vp;padding({ top: 10, left: 15 }) → 顶部内边距10vp,左侧15vp。
-
borderRadius:布局的圆角,示例:borderRadius(10) → 圆角半径10vp,使布局呈现圆角效果。
2. 专属属性
-
Row 专属:无特殊专属属性,主要使用通用属性。
-
Column 专属:无特殊专属属性,主要使用通用属性。
-
Flex 专属:
-
wrap:是否自动换行,值为FlexWrap.Wrap(换行)、FlexWrap.NoWrap(不换行,默认),用于解决组件超出布局宽度的问题。
-
direction:主轴方向,值为FlexDirection.Row(水平,默认)、FlexDirection.Column(垂直),可将Flex转为水平或垂直布局。
-
flexShrink:组件缩小比例,当组件超出布局宽度时,控制组件的缩小比例(默认1,可设置0表示不缩小)。
-
flexGrow:组件放大比例,当布局有剩余空间时,控制组件的放大比例(默认0,不放大)。
-
三、完整实战代码(三大布局结合,可直接运行)
下面我们编写一个完整的实战案例,将Row、Column、Flex三大布局结合起来,实现一个包含导航栏、标签流、按钮组的页面,代码带详细注释,新手可直接复制到IDE中运行,查看效果。
@Entry
@Component
struct LayoutDemoPage {
// 定义标签流数据(用于Flex布局演示)
private tags: string[] = ['鸿蒙开发', 'ArkTS', 'UI布局', 'Row', 'Column', 'Flex', '状态管理', '组件通信'];
build() {
// 页面整体布局:垂直布局(Column)
Column({ space: 20 }) {
// 1. 导航栏(水平布局 Row)
Row() {
// 左侧返回图标
Image($r('app.media.back'))
.width(24)
.height(24)
.margin({ left: 15 });
// 中间标题(水平居中)
Text('三大布局实战演示')
.fontSize(20)
.fontWeight(FontWeight.Bold)
// 占满剩余空间,使标题居中
.flexGrow(1)
.textAlign(TextAlign.Center);
// 右侧设置图标
Image($r('app.media.setting'))
.width(24)
.height(24)
.margin({ right: 15 });
}
.width('100%')
.height(50)
.backgroundColor('#0099ff')
.alignItems(ItemAlign.Center) // 垂直居中(交叉轴对齐)
// 2. Column 垂直布局演示(表单样式)
Column({ space: 15 }) {
Text('Column 垂直布局(表单示例)')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Left)
.width('100%');
// 表单项1:标签+输入框(水平布局)
Row({ space: 10 }) {
Text('用户名:')
.fontSize(16)
.width(80)
.textAlign(TextAlign.Right);
TextInput({ placeholder: '请输入用户名' })
.flexGrow(1)
.height(40)
.border({ width: 1, color: '#ccc' })
.borderRadius(5);
}
// 表单项2:标签+输入框(水平布局)
Row({ space: 10 }) {
Text('密码:')
.fontSize(16)
.width(80)
.textAlign(TextAlign.Right);
TextInput({ placeholder: '请输入密码' })
.flexGrow(1)
.height(40)
.border({ width: 1, color: '#ccc' })
.borderRadius(5)
.type(InputType.Password); // 密码类型,输入内容隐藏
}
// 提交按钮(水平居中)
Button('提交')
.width(120)
.height(40)
.backgroundColor('#0099ff')
.margin({ top: 10 });
}
.width('90%')
.backgroundColor('#f5f5f5')
.padding(15)
.borderRadius(10);
// 3. Flex 弹性布局演示(标签流)
Column({ space: 10 }) {
Text('Flex 弹性布局(标签流示例)')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Left)
.width('100%');
// 弹性布局,自动换行,标签均匀分布
Flex({ wrap: FlexWrap.Wrap }) {
// 循环渲染标签
ForEach(this.tags, (tag: string) => {
Text(tag)
.fontSize(14)
.padding({ left: 12, right: 12, top: 6, bottom: 6 })
.backgroundColor('#e6f7ff')
.fontColor('#0099ff')
.borderRadius(20);
})
}
}
.width('90%')
.backgroundColor('#f5f5f5')
.padding(15)
.borderRadius(10);
// 4. Row 水平布局演示(按钮组)
Row({ space: 15}) {
Button('按钮1')
.width(80)
.height(40)
.backgroundColor('#0099ff');
Button('按钮2')
.width(80)
.height(40)
.backgroundColor('#ff6600');
Button('按钮3')
.width(80)
.height(40)
.backgroundColor('#33cc33');
}
.width('90%')
.backgroundColor('#f5f5f5')
.padding(15)
.borderRadius(10);
}
.width('100%')
.height('100%')
.backgroundColor('#f8f8f8')
.padding({ top: 20 });
}
}
四、运行效果与场景解析
将上述代码复制到Index.ets中,运行应用,会看到以下效果,对应不同的布局场景,帮助大家理解三大布局的实际应用。
1. 导航栏(Row布局)
页面顶部是一个水平布局的导航栏,包含左侧返回图标、中间标题、右侧设置图标:
-
使用Row布局实现水平排列,alignItems(ItemAlign.Center)使图标和标题垂直居中。
-
标题使用flexGrow(1),占满导航栏的剩余空间,实现标题水平居中。
-
导航栏设置固定高度50vp,背景色为蓝色,提升页面质感。
2. 表单(Column+Row布局)
中间部分是一个垂直布局的表单,包含两个表单项和一个提交按钮:
-
外层使用Column布局,实现表单项从上到下排列,space设置为15vp,控制表单项之间的间距。
-
每个表单项使用Row布局,实现标签和输入框水平排列,标签固定宽度80vp,输入框使用flexGrow(1)占满剩余空间,适配不同屏幕。
-
密码输入框设置type(InputType.Password),实现密码隐藏功能。
3. 标签流(Flex布局)
表单下方是一个弹性布局的标签流,包含8个标签:
-
使用Flex布局,设置wrap: FlexWrap.Wrap,实现标签自动换行,避免标签超出屏幕宽度。
-
justifyContent: FlexAlign.SpaceBetween,使标签在每行均匀分布,提升美观度。
-
使用ForEach循环渲染标签数据,实现标签的动态生成,后续可通过修改tags数组添加/删除标签。
4. 按钮组(Row布局)
页面底部是一个水平布局的按钮组,包含3个不同颜色的按钮:
-
使用Row布局,设置justifyContent: FlexAlign.Center,使按钮组水平居中。
-
space设置为15vp,控制按钮之间的间距,按钮设置固定宽高,保证样式统一。
五、复杂场景适配技巧(实战必备)
在实际开发中,我们会遇到多终端适配、组件超出屏幕、布局嵌套等复杂场景,以下是几个常用的适配技巧,帮助大家解决实际开发中的问题。
1. 多终端适配(手机、平板)
-
使用百分比设置宽高(如width: '90%'),避免使用固定值,使布局自适应不同屏幕尺寸。
-
使用flexGrow/flexShrink属性,让组件根据布局空间自动拉伸或缩小,适配不同屏幕宽度。
-
对于平板等宽屏设备,可使用Flex布局的direction属性,在宽屏时改为水平布局,窄屏时改为垂直布局。
2. 组件超出屏幕解决方法
-
Flex布局:设置wrap: FlexWrap.Wrap,实现组件自动换行。
-
文本组件:设置textOverflow: TextOverflow.Ellipsis,实现文本超出时省略显示(如“鸿蒙开发入门...”)。
3. 布局嵌套技巧
-
布局可以无限嵌套,但建议嵌套层数不超过3层,避免影响页面渲染性能。
-
复杂页面可拆分为多个自定义组件,每个组件负责一个小的布局模块,提升代码复用性和可读性。
-
使用padding和margin控制布局间距,避免使用过多的space属性,使布局更灵活。
六、常见问题与解决方案(新手避坑)
-
问题:组件排列混乱,无法居中? 解决方案:检查justifyContent(主轴对齐)和alignItems(交叉轴对齐)属性,确保设置正确,同时确认布局的宽高是否设置合理。
-
问题:Flex布局无法换行? 解决方案:检查wrap属性是否设置为FlexWrap.Wrap,同时确认布局的宽度是否足够(避免设置固定宽高导致组件无法换行)。
-
问题:组件超出布局范围,显示不全? 解决方案:使用scrollable属性实现滚动,或使用flexShrink属性让组件缩小,也可调整布局的宽高和间距。
-
问题:多终端适配时,布局在平板上显示异常? 解决方案:使用百分比和flex相关属性,避免固定宽高,同时可通过媒体查询(MediaQuery)判断设备尺寸,动态调整布局。
总结
本篇详细讲解了Row、Column、Flex三大布局的基础用法、属性详解、实战案例和复杂场景适配技巧,通过一个完整的实战案例,将三大布局结合起来,实现了导航栏、表单、标签流、按钮组等常见页面模块。这三大布局是鸿蒙UI开发的核心,掌握它们,就能完成大部分页面的开发。
建议大家复制代码运行,修改属性(如space、justifyContent、wrap),观察布局的变化,加深理解。下一篇我们将讲解鸿蒙开发中最常用的4个UI组件,带你实现更丰富的页面交互效果。
如果觉得本篇文章有用,欢迎点赞、收藏、关注,后续会持续更新鸿蒙开发系列教程,从基础到进阶,手把手带你学会鸿蒙开发!
更多推荐

所有评论(0)