ArkUI弹性布局(Flex)用法详解(附带实例)
弹性布局提供更加有效的方式对 Flex 容器中的子元素进行排列、对齐和分配剩余空间,通常用于页面头部导航栏的均匀分布、页面框架的搭建和多行数据的排列等。
Flex 容器默认存在主轴与交叉轴,子元素默认沿主轴排列,如下图所示。

图 1 主轴为水平方向的 Flex 容器示意图
子元素在主轴方向的尺寸称为主轴尺寸,在交叉轴方向的尺寸称为交叉轴尺寸。
弹性布局中的基本概念说明如下:

图 2 弹性布局方向图
1) FlexDirection.Row(默认值):主轴为水平方向,子元素从起始端沿着水平方向开始排布。示例代码如下:
显示效果如下图所示:

图 3 FlexDirection.Row方向显示效果
2) FlexDirection.RowReverse:主轴为水平方向,子元素从终点端沿着 FlexDirection.Row 相反的方向开始排布。示例代码如下:

图 4 FlexDirection.RowReverse方向显示效果
3) FlexDirection.Column:主轴为垂直方向,子元素从起始端沿着垂直方向开始排布。示例代码如下:

图 5 FlexDirection.Column方向显示效果
4) FlexDirection.ColumnReverse:主轴为垂直方向,子元素从终点端沿着 FlexDirection.Column 相反的方向开始排布。示例代码如下:

图 6 FlexDirection.ColumnReverse方向显示效果
wrap 属性的取值有以下 3 种:
1) FlexWrap.NoWrap(默认值):不换行。如果子元素的宽度总和大于父元素的宽度,则子元素的宽度会被压缩。示例代码如下:

图 7 FlexWrap.NoWrap显示效果
2) FlexWrap.Wrap:换行,每一行子元素按照主轴方向排列。示例代码如下:

图 8 FlexWrap.Wrap显示效果
3) FlexWrap.WrapReverse:换行,每一行子元素按照主轴反方向排列。示例代码如下:

图 9 FlexWrap.WrapReverse显示效果

图 10 子元素在主轴方向的对齐方式
1) FlexAlign.Start(默认值):子元素在主轴方向起始端对齐,第一个子元素与父元素边沿对齐,其他元素与前一个元素对齐。示例代码如下:

图 11 FlexAlign.Start显示效果
2) FlexAlign.Center:子元素在主轴方向居中对齐。示例代码如下:

图 12 FlexAlign.Center显示效果
3) FlexAlign.End:子元素在主轴方向终点端对齐,最后一个子元素与父元素边沿对齐,其他元素与后一个元素对齐。示例代码如下:

图 13 FlexAlign.End显示效果
4) FlexAlign.SpaceBetween:各行子元素将沿交叉轴均匀分布,第一行与交叉轴起始端对齐,最后一行与交叉轴结束端对齐,其余的行将根据剩余空间进行均匀分布。示例代码如下:

图 14 FlexAlign.SpaceBetween显示效果
5) FlexAlign.SpaceAround:各行子元素将在交叉轴上均匀分布,行与行之间的距离相等,同时第一行到交叉轴起始端的距离与最后一行到交叉轴结束端的距离相等,并且是行间距离的一半。示例代码如下:

图 15 FlexAlign.SpaceAround显示效果
6) FlexAlign.SpaceEvenly:各行子元素的间距、第一行到交叉轴起始端的距离与最后一行到交叉轴结束端的距离都相等。示例代码如下:

图 16 FlexAlign.SpaceEvenly显示效果
Flex 容器默认存在主轴与交叉轴,子元素默认沿主轴排列,如下图所示。

图 1 主轴为水平方向的 Flex 容器示意图
子元素在主轴方向的尺寸称为主轴尺寸,在交叉轴方向的尺寸称为交叉轴尺寸。
弹性布局中的基本概念说明如下:
- 主轴:Flex 组件布局方向的轴线,子元素默认沿着主轴排列。主轴开始位置称为主轴起始点,结束位置称为主轴结束点。
- 交叉轴:垂直于主轴方向的轴线。交叉轴开始位置称为交叉轴起始点,结束位置称为交叉轴结束点。
布局方向
在弹性布局中,Flex 容器的子元素可以按照任意方向排列。通过设置参数 direction,可以决定主轴的方向,从而控制子元素的排列方向,如下图所示。
图 2 弹性布局方向图
1) FlexDirection.Row(默认值):主轴为水平方向,子元素从起始端沿着水平方向开始排布。示例代码如下:
@Entry @Component struct FlexSample { build() { // 弹性布局组件,设置布局方向为水平方向 Flex({ direction: FlexDirection.Row }) { // 设置子组件宽度为父容器宽度的1/3 Text('1').width('33%').height(50).backgroundColor(0xF5DEB3) // 设置子组件宽度为父容器宽度的1/3 Text('2').width('33%').height(50).backgroundColor(0xD2B48C) // 设置子组件宽度为父容器宽度的1/3 Text('3').width('33%').height(50).backgroundColor(0xF5DEB3) }.height(70).width('90%') // 设置内填充边距为10vp .padding(10).backgroundColor(0xAFEEEE) } }
显示效果如下图所示:

图 3 FlexDirection.Row方向显示效果
2) FlexDirection.RowReverse:主轴为水平方向,子元素从终点端沿着 FlexDirection.Row 相反的方向开始排布。示例代码如下:
@Entry @Component struct FlexSample { build() { // 设置子组件排列放方向为行的反向,即从右向左 Flex({ direction: FlexDirection.RowReverse }) { Text('1').width('33%').height(50).backgroundColor(0xF5DEB3) Text('2').width('33%').height(50).backgroundColor(0xD2B48C) Text('3').width('33%').height(50).backgroundColor(0xF5DEB3) }.height(70).width('90%').padding(10).backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 4 FlexDirection.RowReverse方向显示效果
3) FlexDirection.Column:主轴为垂直方向,子元素从起始端沿着垂直方向开始排布。示例代码如下:
@Entry @Component struct FlexSample { build() { // 弹性布局组件,设置子组件排列方向为从上向下 Flex({ direction: FlexDirection.Column }) { Text('1').width('100%').height(50).backgroundColor(0xF5DEB3) Text('2').width('100%').height(50).backgroundColor(0xD2B48C) Text('3').width('100%').height(50).backgroundColor(0xF5DEB3) }.height(70).width('90%').padding(10).backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 5 FlexDirection.Column方向显示效果
4) FlexDirection.ColumnReverse:主轴为垂直方向,子元素从终点端沿着 FlexDirection.Column 相反的方向开始排布。示例代码如下:
@Entry @Component struct FlexSample { build() { // 弹性布局组件,子组件排列方向为从下向上 Flex({ direction: FlexDirection.ColumnReverse }) { Text('1').width('100%').height(50).backgroundColor(0xF5DEB3) Text('2').width('100%').height(50).backgroundColor(0xD2B48C) Text('3').width('100%').height(50).backgroundColor(0xF5DEB3) }.height(70).width('90%').padding(10).backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 6 FlexDirection.ColumnReverse方向显示效果
布局换行
弹性布局分为单行布局和多行布局。默认情况下,Flex 容器中的子元素都排在一条轴线上。当子元素主轴尺寸之和大于容器主轴尺寸时,可以使用 wrap 属性控制 Flex 是单行布局还是多行布局。在多行布局时,通过交叉轴方向,确认新行排列方向。wrap 属性的取值有以下 3 种:
1) FlexWrap.NoWrap(默认值):不换行。如果子元素的宽度总和大于父元素的宽度,则子元素的宽度会被压缩。示例代码如下:
@Entry @Component struct FlexSample { build() { // 弹性布局组件,设置不换行 Flex({ wrap: FlexWrap.NoWrap }) { // 下列3个组件的宽度超过了弹性布局组件的宽度,但是不换行,最终变为均匀分配宽度 // 子组件宽度设置为父容器组件的50% Text('1').width('50%').height(50).backgroundColor(0xF5DEB3) // 子组件宽度设置为父容器组件的50% Text('2').width('50%').height(50).backgroundColor(0xD2B48C) // 子组件宽度设置为父容器组件的50% Text('3').width('50%').height(50).backgroundColor(0xF5DEB3) }.width('90%').padding(10).backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 7 FlexWrap.NoWrap显示效果
2) FlexWrap.Wrap:换行,每一行子元素按照主轴方向排列。示例代码如下:
@Entry @Component struct FlexSample { build() { // 弹性布局组件,设置换行,子组件按照弹性布局组件的主轴方向排列 Flex({ wrap: FlexWrap.Wrap }) { // 子组件宽度设置为父容器组件宽度的50% Text('1').width('50%').height(50).backgroundColor(0xF5DEB3) // 子组件宽度设置为父容器组件宽度的50% Text('2').width('50%').height(50).backgroundColor(0xD2B48C) // 子组件宽度设置为父容器组件宽度的50% Text('3').width('50%').height(50).backgroundColor(0xD2B48C) }.width('90%').padding(10).backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 8 FlexWrap.Wrap显示效果
3) FlexWrap.WrapReverse:换行,每一行子元素按照主轴反方向排列。示例代码如下:
@Entry @Component struct FlexSample { build() { // 弹性布局组件,设置反向排列子组件,如果换行,则反向换行 Flex({ wrap: FlexWrap.WrapReverse }) { Text('1').width('50%').height(50).backgroundColor(0xF5DEB3) Text('2').width('50%').height(50).backgroundColor(0xD2B48C) Text('3').width('50%').height(50).backgroundColor(0xF5DEB3) }.width('90%').padding(10).backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 9 FlexWrap.WrapReverse显示效果
主轴对齐方式
通过 justifyContent 参数设置子元素在主轴方向的对齐方式,如下图所示:
图 10 子元素在主轴方向的对齐方式
1) FlexAlign.Start(默认值):子元素在主轴方向起始端对齐,第一个子元素与父元素边沿对齐,其他元素与前一个元素对齐。示例代码如下:
// 通过Record设置布局参数 let PTopBottom: Record<string, number> = { 'top': 10, 'bottom': 10 } @Entry @Component struct FlexSample { build() { // 子元素在主轴方向起始端对齐, 第一个子元素与父元素边沿对齐,其他元素与前一个元素对齐 Flex({ justifyContent: FlexAlign.Start }) { Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) Text('2').width('20%').height(50).backgroundColor(0xD2B48C) Text('3').width('20%').height(50).backgroundColor(0xF5DEB3) }.width('90%') // 通过Record类型数据设置内填充边距 .padding(PTopBottom) .backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 11 FlexAlign.Start显示效果
2) FlexAlign.Center:子元素在主轴方向居中对齐。示例代码如下:
// 通过Record设置布局参数 let PTopBottom: Record<string, number> ={ 'top': 10, 'bottom': 10 } @Entry @Component struct FlexSample { build() { // 弹性布局,子组件在水平方向居中对齐 Flex({ justifyContent: FlexAlign.Center }) { Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) Text('2').width('20%').height(50).backgroundColor(0xD2B48C) Text('3').width('20%').height(50).backgroundColor(0xF5DEB3) }.width('90%') // 使用Record类型数据设置内填充边距 .padding(PTopBottom) .backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 12 FlexAlign.Center显示效果
3) FlexAlign.End:子元素在主轴方向终点端对齐,最后一个子元素与父元素边沿对齐,其他元素与后一个元素对齐。示例代码如下:
@Entry @Component struct FlexSample { build() { Flex({ // 设置子组件在主轴方向上的排列方式 // 子组件之间等距排列,第一个子组件与父组件起始位置对齐,最后一个子组件与父组件结束位置对齐 justifyContent: FlexAlign.SpaceBetween, // 如果主轴方向空间不够,则换行 wrap: FlexWrap.Wrap, // 在交叉轴方向上,如果父组件空间有剩余,则子组件在交叉轴方向的对齐方式为:与交叉轴结束端对齐 alignContent: FlexAlign.End }) { Text('1').width('30%').height(20).backgroundColor(Color.White) Text('2').width('60%').height(20).backgroundColor(Color.Blue).fontColor(Color.Yellow) Text('3').width('40%').height(20).backgroundColor(Color.Brown).fontColor(Color.Yellow) Text('4').width('30%').height(20).backgroundColor(Color.Green).fontColor(Color.Yellow) Text('5').width('20%').height(20).backgroundColor(0xD2B48C) }.width('90%').height(100).backgroundColor(0xAFEEEEE) } }显示效果如下图所示:

图 13 FlexAlign.End显示效果
4) FlexAlign.SpaceBetween:各行子元素将沿交叉轴均匀分布,第一行与交叉轴起始端对齐,最后一行与交叉轴结束端对齐,其余的行将根据剩余空间进行均匀分布。示例代码如下:
@Entry @Component struct FlexSample { build() { Flex({ // 设置子组件在主轴方向上的对齐方式 // 子组件之间等间距排列,第一个子组件与主轴起点位置对齐,最后一个子组件与主轴结束位置对齐 justifyContent: FlexAlign.SpaceBetween, // 如果主轴方向空间不够,则换行 wrap: FlexWrap.Wrap, // 在交叉轴方向上如果有剩余空间,则子组件的对齐方式为: // 行之间等距排列,各行与交叉轴两端对齐 alignContent: FlexAlign.SpaceBetween }) { Text('1').width('30%').height(20).backgroundColor(Color.Black) .fontColor(Color.White) Text('2').width('60%').height(20).backgroundColor(Color.Blue) .fontColor(Color.Yellow) Text('3').width('40%').height(20).backgroundColor(Color.Green) .fontColor(Color.Yellow) Text('4').width('30%').height(20).backgroundColor(Color.Brown) .fontColor(Color.Yellow) Text('5').width('20%').height(20).backgroundColor(Color.Red) .fontColor(Color.Yellow) }.width('90%').height(100).backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 14 FlexAlign.SpaceBetween显示效果
5) FlexAlign.SpaceAround:各行子元素将在交叉轴上均匀分布,行与行之间的距离相等,同时第一行到交叉轴起始端的距离与最后一行到交叉轴结束端的距离相等,并且是行间距离的一半。示例代码如下:
@Entry @Component struct FlexSample { build() { Flex({ // 子组件在主轴方向上的排列方式:首尾子组件分别与主轴的开始和结束位置对齐 // 子组件之间等距排列 justifyContent: FlexAlign.SpaceBetween, // 如果主轴方向空间不够,则换行 wrap: FlexWrap.Wrap, // 在交叉轴方向上如果有剩余空间,则子组件的对齐方式: // 行与行之间等距排列,第一行到交叉轴起始端的距离与最后一行到交叉轴结束端的距离为行间距的一半 alignContent: FlexAlign.SpaceAround }) { Text('1').width('30%').height(20).backgroundColor(Color.White) .fontColor(Color.Black) Text('2').width('60%').height(20).backgroundColor(Color.Blue) .fontColor(Color.Yellow) Text('3').width('40%').height(20).backgroundColor(Color.Green) .fontColor(Color.Yellow) Text('4').width('30%').height(20).backgroundColor(Color.Red) .fontColor(Color.Yellow) Text('5').width('20%').height(20).backgroundColor(Color.Yellow) .fontColor(Color.Black) }.width('90%').height(100).backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 15 FlexAlign.SpaceAround显示效果
6) FlexAlign.SpaceEvenly:各行子元素的间距、第一行到交叉轴起始端的距离与最后一行到交叉轴结束端的距离都相等。示例代码如下:
@Entry @Component struct FlexSample { build() { Flex({ // 子组件在主轴方向上的排列方式:首尾子组件分别与主轴的开始和结束位置对齐 // 子组件之间等距排列 justifyContent: FlexAlign.SpaceBetween, // 在主轴方向上如果空间不够,则换行显示子组件 wrap: FlexWrap.Wrap, // 在交叉轴方向上如果有剩余空间,则子组件的排列方式: // 各行子元素的间距、第一行到交叉轴起始端的距离与最后一行到交叉轴结束端的距离都相等 alignContent: FlexAlign.SpaceEvenly }) { Text('1').width('30%').height(20).backgroundColor(Color.Black) .fontColor(Color.White) Text('2').width('60%').height(20).backgroundColor(Color.Blue) .fontColor(Color.Yellow) Text('3').width('40%').height(20).backgroundColor(Color.Green) .fontColor(Color.Yellow) Text('4').width('30%').height(20).backgroundColor(Color.Red) .fontColor(Color.Yellow) Text('5').width('20%').height(20).backgroundColor(Color.Yellow) .fontColor(Color.Black) }.width('90%').height(100).backgroundColor(0xAFEEEE) } }显示效果如下图所示:

图 16 FlexAlign.SpaceEvenly显示效果