四.布局高级
1. 弹性布局(Flex)
弹性布局(Flex)提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间。常用于页面头部导航栏的均匀分布、页面框架的搭建、多行数据的排列等。
容器默认存在主轴与交叉轴,子元素默认沿主轴排列,子元素在主轴方向的尺寸称为主轴尺寸,在交叉轴方向的尺寸称为交叉轴尺寸。
1.1 基本使用
弹性容器组件:Flex()
Flex(参数对象) {
子组件1
子组件2
子组件3
子组件N
}
build() {
Flex() {
Text('1')
.width('33%')
.height(30)
.backgroundColor(Color.Orange)
Text('2')
.width('33%')
.height(30)
.backgroundColor(Color.Pink)
Text('3')
.width('33%')
.height(30)
.backgroundColor(Color.Orange)
}
.width('100%')
.height(200)
.backgroundColor('#ccc')
}
1.2 布局方向
在弹性布局中,容器的子元素可以按照任意方向排列(默认水平排列)。通过设置参数 direction
,可以决定主轴的方向,从而控制子元素的排列方向
参数:direction
值:枚举 FlexDirection
枚举值 | 描述 |
---|---|
Row | 主轴为水平方向 |
RowReverse | 相反的水平方向 |
Colume | 主轴为垂直方向 |
ColumnReverse | 相反的垂直方向 |
Flex({ direction:FlexDirection.Column }) {
Text('1')
.width('33%')
.height(30)
.backgroundColor(Color.Orange)
Text('2')
.width('33%')
.height(30)
.backgroundColor(Color.Pink)
Text('3')
.width('33%')
.height(30)
.backgroundColor(Color.Orange)
}
.width('100%')
.height(200)
.backgroundColor('#ccc')
1.3 主轴对齐方式
参数: justifyContent
值:枚举 FlexAlign
(属性与线性布局主轴对齐方式相同)
Flex({justifyContent:FlexAlign.SpaceBetween}){
Text('1')
.width(30)
.height(30)
.backgroundColor(Color.Orange)
Text('2')
.width(30)
.height(30)
.backgroundColor(Color.Pink)
Text('3')
.width(30)
.height(30)
.backgroundColor(Color.Orange)
Text('4')
.width(30)
.height(30)
.backgroundColor(Color.Pink)
}
.width('100%')
.height(100)
.backgroundColor('#ccc')
}
1.4 交叉轴对齐方式
参数: alignItems
值:枚举 ItemAlign
build() {
Flex({direction:FlexDirection.Column,justifyContent:FlexAlign.spaceBetween,alignItems:ItemAlign.Start}) {
Text('1')
.width(30)
.height(30)
.backgroundColor(Color.Orange)
Text('2')
.width(30)
.height(30)
.backgroundColor(Color.Pink)
// 交叉轴拉伸
.alignSelf(ItemAlign.Stretch)
Text('3')
.width(30)
.height(30)
.backgroundColor(Color.Orange)
Text('4')
.width(30)
.height(30)
.backgroundColor(Color.Pink)
}
.width('100%')
.height(200)
.backgroundColor('#ccc')
}
子元素的 alignSelf
属性也可以设置子元素在父容器交叉轴的对齐格式,且会覆盖 Flex 布局容器中alignItems
配置
1.5 布局换行
弹性布局分为单行布局和多行布局。默认情况下,Flex 容器中的子元素都排在一条线(又称“轴线”)上。子元素尺寸总和大于 Flex 容器尺寸时,子元素尺寸会自动挤压。
wrap
属性控制当子元素主轴尺寸之和大于容器主轴尺寸时,Flex 是单行布局还是多行布局。在多行布局时,通过交叉轴方向,确认新行排列方向。
参数:wrap
值:枚举 FlexWrap
build() {
Flex({ wrap:FlexWrap.Wrap }) {
Text('1')
.width('33%')
.height(30)
.backgroundColor(Color.Orange)
Text('2')
.width('33%')
.height(30)
.backgroundColor(Color.Pink)
Text('3')
.width('33%')
.height(30)
.backgroundColor(Color.Orange)
Text('4')
.width('33%')
.height(30)
.backgroundColor(Color.Pink)
}
.width('100%')
.height(200)
.backgroundColor('#ccc')
}
1.6 自适应拉伸
1.6.1 flexGrow
作用:设置父容器的剩余空间分配给此属性所在组件的比例。用于分配父组件的剩余空间
属性:flexGrow(数字)
参数:数字,占用父级剩余尺寸的份数
Flex() {
Text('1')
.width(50)
.aspectRatio(1)
.backgroundColor(Color.White)
Text('2')
.width(50)
.aspectRatio(1)
.backgroundColor(Color.Green)
//占用父空间剩余2份
.flexGrow(2)
Text('3')
.width(50)
.aspectRatio(1)
.backgroundColor(Color.Blue)
//占用父空间剩余1份
.flexGrow(1)
}
1.6.2 flexBasis
作用:设置子元素在父容器主轴方向上的基准尺寸。
属性:flexBasis(数字)
参数:数字,基准尺寸(单位vp)。
build() {
Column() {
Flex() {
Text('1')
.width(50)
.aspectRatio(1)
.backgroundColor(Color.White)
Text('2')
.width(50)
.aspectRatio(1)
.backgroundColor(Color.Green)
.flexGrow(1)
Text('3')
.width(50)
.aspectRatio(1)
.backgroundColor(Color.Blue)
.flexBasis(130)
}
}
.width('100%')
.height('100%')
.backgroundColor(Color.Gray)
2.1 定位
-
作用:改变组件位置
分类:
-
绝对定位:
position
,相对父组件左上角进行偏移 -
相对定位:
offset
,相对自身左上角进行偏移
-
2.1 绝对定位
属性:position()
参数:{x: 水平偏移量, y: 垂直偏移量}
偏移量取值
-
数字,单位是
vp
-
百分比,参照父组件尺寸计算结果
@Entry
@Component
struct Index {
build() {
Column() {
Text('文字内容')
.width(80)
.height(40)
.backgroundColor(Color.Pink)
.position({
x: 0,
y: 0
})
}
.width('100%')
.height(200)
.backgroundColor('#ccc')
}
}
绝对定位特点:
-
参照父组件左上角进行偏移
-
绝对定位后的组件不再占用自身原有位置
2.2 相对定位
属性:offset()
参数:{x: 水平偏移量, y: 垂直偏移量}
偏移量取值
-
数字,单位是
vp
-
百分比,参照父组件尺寸计算结果
@Entry
@Component
struct Index {
build() {
Column() {
Text('内容1')
.width(80)
.height(40)
.backgroundColor(Color.Pink)
Text('内容2')
.width(80)
.height(40)
.backgroundColor(Color.Orange)
// 占位
.offset({
x: 100,
y: -30
})
Text('内容3')
.width(80)
.height(40)
.backgroundColor(Color.Brown)
}
.width('100%')
.height(200)
.backgroundColor('#ccc')
}
}
相对定位特点:
-
相对自身左上角进行偏移
-
相对定位后的组件仍然占用自身原有位置
2.3 Z序控制
定位后的组件,默认后定义的组件在最上面显示,可以通过 zIndex 属性调整显示层级
属性:zIndex(数字)
特点:取值为整数数字,取值越大,显示层级越高
Column() {
Text('文字内容1')
.width(80)
.height(40)
.backgroundColor(Color.Pink)
.position({
x: 0,
y: 0
})
.zIndex(1)
Text('文字内容2')
.width(80)
.height(40)
.backgroundColor(Color.Brown)
.position({
x: 50,
y: 0
})
}
.width('100%')
.height(200)
.backgroundColor('#ccc')
3.层叠布局
层叠布局(StackLayout)用于在屏幕上预留一块区域来显示组件中的元素,提供元素可以重叠的布局。层叠布局通过 Stack 容器组件实现位置的固定定位与层叠,容器中的子元素依次入栈,后一个子元素覆盖前一个子元素,子元素可以叠加,也可以设置位置。
层叠布局具有较强的页面层叠、位置定位能力,其使用场景有广告、卡片层叠效果等。
3.1 基本使用
Stack 组件为容器组件,容器内可包含各种子元素。其中子元素默认进行居中堆叠。子元素被约束在Stack下,进行自己的样式定义以及排列。
Column(){
Stack() {
Column(){}
.width('90%')
.height(130)
.backgroundColor(Color.Gray)
Text('text')
.width('60%')
.height('60%')
.backgroundColor(Color.Orange)
Button('button')
.width('30%')
.height('30%')
.backgroundColor('#ff8ff3eb')
.fontColor('#000')
}
.width('100%')
.height(150)
.backgroundColor(Color.Pink)
}
.margin(10)
3.2 对齐方式
参数:alignContent
取值:枚举 Alignment
Column() {
Stack({alignContent:Alignment.Bottom}) {
//图片下方文字
Row(){
//左
Row(){
Text('1')
Text('2')
}
//右
Row(){
Text('3')
}
}
.justifyContent(FlexAlign.SpaceBetween)
.width('100%')
.height(50)
.backgroundColor(Color.Yellow)
}
.width('100%')
.height('100%')
.backgroundColor(Color.Orange)
}
.width('100%')
.height(200)
.backgroundColor('#ccc')
3,3 Z序控制
属性:zIndex(数字)
特点:取值为整数数字,取值越大,显示层级越高
Column(){
Stack({ alignContent: Alignment.BottomEnd }) {
Column(){}
.width('90%')
.height(130)
.backgroundColor(Color.Gray)
Text('text')
.width('60%')
.height('60%')
.backgroundColor('rgba(0,0,0,0.3)')
// Z 序:显示在按钮上一层
.zIndex(1)
Button('button')
.width('30%')
.height('30%')
.backgroundColor('#ff8ff3eb')
.fontColor('#000')
}
.width('100%')
.height(150)
.backgroundColor(Color.Pink)
}
.margin(10)