ArkUI 弹性布局(Flex)-官方文档:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-layout-development-flex-layout-V5
弹性布局(Flex)的效果类似于线性布局(Column/Row),也会使子元素呈线性排列,但是弹性布局在子元素的排列、对齐和剩余空间的分配等方面更加灵活。
Flex组件的参数定义如下,下面逐一介绍每个属性
Flex(value?: { direction?: FlexDirection, justifyContent?: FlexAlign, alignItems?: ItemAlign, wrap?: FlexWrap, alignContent?: FlexAlign })
dirction
用于设置Flex容器的布局方向,即子元素的排列方向,其类型FlexDirection
为枚举类型,可选的枚举值如下
名称 | Row | RowReverse | Column | ColumnReverse |
---|---|---|---|---|
描述 | 水平方向,元素从左到右排列 | 水平方向,元素从右到左排列 | 垂直方向,元素从上到下排列 | 垂直方向,元素从下到上排列 |
效果 |
Flex容器中也有主轴和交叉轴两个概念,其中主轴方向与direction
一致,交叉轴与主轴垂直,具体方向如下
direction | Row | RowReverse | Column | ColumnReverse |
---|---|---|---|---|
主轴和交叉轴 |
img
基本概念
justifyContent
参数的作用同Column/Row容器的justifyContent()
完全相同,也是用于设置子元素在主轴方向的排列方式,其类型同样为FlexAlign
,可选的枚举值如下
名称 | 描述 | 效果(以direction=Row为例) |
---|---|---|
Start | 分布在起始端 | |
Center | 居中 | |
End | 分布在结束端 | |
SpaceBetween | 均匀分布,首尾两项两端对齐,中间元素等间距分布 | |
SpaceAround | 均匀分布,所有子元素两侧都留有相同的空间 | |
SpaceEvenly | 均匀分布,所有子元素之间以及首尾两元素到两端的距离都相等 |
alignItems
参数的作用同Column/Row容器的alignItems()
相同,也是用于设置子元素在交叉轴的对齐方式。但该参数的类型与Column/Row容器的alignItems()
方法不同,为ItemAlign
,可选的枚举值有
名称 | 描述 | 效果(以direction=Row为例) |
---|---|---|
Start | 启始端对齐 | |
Center | 居中对齐 | |
End | 结束端对齐 | |
Stretch | 拉伸到容器尺寸 | |
BaseLine | 沿文本基线对齐(限于Text文本组件)基线是西文书法或印刷学中的一个概念,它指的是多数字母底部的那条线,如下图所示 |
默认情况下,Flex容器的子组件,都排在一条线(主轴)上。当子组件在主轴方向的尺寸之和大于Flex容器时,为适应容器尺寸,所有子组件的尺寸都会自动收缩。如果需要保持子组件的尺寸不收缩,也可选择令子组件**换行(列)**显示。
wrap
属性的作用就是控制如何换行,该属性的类型FlexWrap
为枚举类型,可选的枚举值如下
名称 | 描述 | 效果(以direction=Row为例) |
---|---|---|
NoWrap | 不换行 | |
Wrap | 换行,每一行子组件按照主轴方向排列 | |
WrapReverse | 换行,每一行子元素按照主轴反方向排列 |
当Flex容器中包含多行(列)时,可使用alignContent
设置多行在交叉轴的排列方式,该属性的类型为FlexAlign
,可选的枚举值如下
名称 | Start | Center | End | SpaceBetween | SpaceAround | SpaceEvenly |
---|---|---|---|---|---|---|
描述 | 分布在起始端 | 居中 | 分布在终点端 | 均匀分布,首尾两项两端对齐,中间元素等间距分布 | 均匀分布,所有子元素两侧都留有相同的空间 | 均匀分布,所有子元素之间以及首尾两元素到两端的距离都相等 |
效果(以direction=Row为例) |
Flex容器的子组件可以使用alignSelf()
方法单独设置自己的交叉轴对齐方式,并且其优先级高于Flex容器alignItems
。具体效果如下
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) { // 容器组件设置子元素居中
Text('alignSelf Start').width('25%').height(80)
.alignSelf(ItemAlign.Start)
.backgroundColor(0xF5DEB3)
Text('alignSelf Baseline')
.alignSelf(ItemAlign.Baseline)
.width('25%')
.height(80)
.backgroundColor(0xD2B48C)
Text('alignSelf Baseline').width('25%').height(100)
.backgroundColor(0xF5DEB3)
.alignSelf(ItemAlign.Baseline)
Text('no alignSelf').width('25%').height(100)
.backgroundColor(0xD2B48C)
Text('no alignSelf').width('25%').height(100)
.backgroundColor(0xF5DEB3)
}.width('90%').height(220).backgroundColor(0xAFEEEE)
说明:
alignSelf()
的参数类型和alignItems()
相同,均为ItemAlign
枚举类型,且各枚举值的含义也完全相同。
弹性布局的显著特点之一是子组件沿主轴方向的尺寸具有弹性,即子组件的大小能够随着Flex容器尺寸的变化而自动伸缩。这种弹性特性使得Flex布局能够使子组件更灵活地适应不同的屏幕尺寸和设备。和自适应伸缩的相关的属性有flexShrink
、flexGrow
和flexBasis
,下面逐一介绍
flexShrink
用于设置父容器空间不足时,子组件的压缩比例,尺寸的具体计算逻辑如下
Flex({ direction: FlexDirection.Row }) {
Text('flexShrink(3)')
.flexShrink(3)
.width(200)
.height(100)
.backgroundColor(0xF5DEB3)
Text('no flexShrink')
.width(200)
.height(100)
.backgroundColor(0xD2B48C)
Text('flexShrink(2)')
.flexShrink(2)
.width(200)
.height(100)
.backgroundColor(0xF5DEB3)
}.width(400).height(120).padding(10).backgroundColor(0xAFEEEE)
flexGrow
用于设置父容器空间充足时,组件瓜分剩余空间的比例,尺寸的具体计算逻辑如下
Flex() {
Text('flexGrow(2)')
.flexGrow(2)
.width(100)
.height(100)
.backgroundColor(0xF5DEB3)
Text('flexGrow(3)')
.flexGrow(3)
.width(100)
.height(100)
.backgroundColor(0xD2B48C)
Text('no flexGrow')
.width(100)
.height(100)
.backgroundColor(0xF5DEB3)
}.width(420).height(120).padding(10).backgroundColor(0xAFEEEE)
父容器宽度420vp,三个子元素原始宽度为100vp,左右padding为20vp,总和320vp,剩余空间100vp根据flexGrow值的占比分配给子元素,未设置flexGrow的子元素不参与“瓜分”。
第一个元素以及第二个元素以2:3分配剩下的100vp。第一个元素为100vp+100vp * 2/5=140vp,第二个元素为100vp+100vp * 3/5=160vp。
flexBasis
用于设置子组件沿主轴方向的尺寸,相当于width
或者height
的作用。若设置了flexBasis
,则以flexBasis
为准,否则以widht
或者height
为准。
Flex() {
Text('flexBasis("auto")')
.flexBasis('auto') // 未设置width以及flexBasis值为auto,内容自身宽度
.height(100)
.backgroundColor(0xF5DEB3)
Text('flexBasis("auto")'+' width("40%")')
.width('40%')
.flexBasis('auto') //设置width以及flexBasis值auto,使用width的值
.height(100)
.backgroundColor(0xD2B48C)
Text('flexBasis(100)') // 未设置width以及flexBasis值为100,宽度为100vp
.flexBasis(100)
.height(100)
.backgroundColor(0xF5DEB3)
Text('flexBasis(100)')
.flexBasis(100)
.width(200) // flexBasis值为100,覆盖width的设置值,宽度为100vp
.height(100)
.backgroundColor(0xD2B48C)
}.width('90%').height(120).padding(10).backgroundColor(0xAFEEEE)