提示:本文根据b站尚硅谷2024最新鸿蒙开发HarmonyOS4.0+鸿蒙NEXT星河版零基础教程课整理
链接指引 => 尚硅谷2024最新鸿蒙开发HarmonyOS4.0+鸿蒙NEXT星河版零基础教程
一、布局基础
1.1 盒子模型
在鸿蒙应用中,页面上的每个组件都可以看做是一个矩形的盒子,这个盒子包含了内容区域(content)
、边框(border)
、内边距(padding)
和外边距(margin)
,各部分内容如下图所示
margin
margin(value: { top?:Length, right?:Length, bottom?:Length, left?:Length } | Length )
说明:
Length=string | number | Resource
当参数类型为Length时,四个方向的边距同时生效padding
padding(value: { top?:Length, right?:Length, bottom?:Length, left?:Length } | Length )
border
border(value: {width?:Length, color?:ResourceColor, radius?:Length, style?:BorderStyle })
各属性含义如下
- width
width
属性表示边框宽度 - color
color
属性表示边框颜色 - radius
radius
属性表示边框圆角半径 style
style
属性表示边框样式,可通过BorderStyle
这一枚举类型进行设置,可选的枚举值有|名称| 描述| 效果|
|--|--|--|
|BorderStyle.Dotted| 显示为一系列圆点 ||
|BorderStyle.Dashed |显示为一系列短的方形虚线 | |
|BorderStyle.Solid |显示为一条实线 ||
- width
二、线性布局(Column/Row)
2.1 概述
线性布局(LinearLayout)是开发中最常用的布局,可通过容器组件Column和Row构建,其子组件会在垂直或者水平方向上进行线性排列,具体效果如下图所示
说明
Column和Row容器均有两个轴线,分别是主轴和交叉轴
- **主轴**:线性布局容器在布局方向上的轴线,`Row`容器主轴为横向,`Column`容器主轴为纵向。
- **交叉轴**:垂直于主轴方向的轴线。`Row`容器交叉轴为纵向,`Column`容器交叉轴为横向。
2.2 参数
Column
和Row
容器的参数类型为{space?: string | number}
,开发者可通过space
属性调整子元素在主轴方向上的间距,效果如下
2.3 常用属性
2.3.1 子元素沿主轴方向的排列方式
子元素沿主轴方向的排列方式可以通过justifyContent()
方法进行设置,其参数类型为枚举类型FlexAlign
,可选的枚举值有
名称 | Start | Center | End | SpaceBetween | SpaceAround | SpaceEvenly |
---|---|---|---|---|---|---|
描述 | 头部对齐 | 居中对齐 | 尾部对齐 | 均匀分布,首尾两项两端对齐,中间元素等间距分布 | 均匀分布,所有子元素两侧都留有相同的空间 | 均匀分布,所有子元素之间以及首尾两元素到两端的距离都相等 |
效果 (以Column容器为例) |
2.3.2 子元素沿交叉轴方向的对齐方式
子元素沿交叉轴方向的对齐方式可以通过alignItems()
方法进行设置,其参数类型,对于Column
容器来讲是HorizontalAlign
,对于Row
容器来讲是VerticalAlign
,两者都是枚举类型,可选择枚举值也都相同,具体内容如下
名称 | start | Center | End |
---|---|---|---|
描述 | 头部对齐 | 居中对齐 | 尾部对齐 |
效果(以Column容器为例) |
2.4 实用技巧
2.4.1 Blank组件的使用
Blank
可作为Column
和Row
容器的子组件,该组件不显示任何内容,并且会始终充满容器主轴方向上的剩余空间,效果如下:
2.4.2 layoutWeight属性的使用
layoutWeight
属性可用于Column
和Row
容器的子组件,其作用是配置子组件在主轴方向上的尺寸权重。配置该属性后,子组件沿主轴方向的尺寸设置(width或height)
将失效
,具体尺寸根据权重进行计算,计算规则如下图所示:
三、层叠布局(Stack)
3.1 概述
层叠布局是指将多个组件沿垂直于屏幕的方向堆叠在一起,类似于图层的叠加。以下效果都可以通过层叠布局实现
层叠布局可通过Stack
容器组件实现,其子元素会按照其添加顺序依次叠加在一起,后添加的子元素位于先添加的子元素之上。具体效果如下
Stack() {
Row()
.width(250)
.height(250)
.backgroundColor('#107B02') //绿色
.shadow({radius:50})
Row()
.width(200)
.height(200)
.backgroundColor('#E66826') //橙色
.shadow({radius:50})
Row()
.width(150)
.height(150)
.backgroundColor('#255FA7') //蓝色
.shadow({radius:50})
}
.width(300)
.height(300)
.backgroundColor('#E5E5E5') //灰色
3.2 参数
Stack
组件的参数类型为{ alignContent?: Alignment }
,alignContent
用于设置子组件的对齐方式,该属性可通过枚举类型Alignment
进行设置,可选的枚举值及其效果如下图所示
3.3 实用技巧
3.3.1 子组件Z轴控制
Stack
容器中子组件的层级除了可按照添加顺序决定,还能通过zIndex()
进行手动的设置,zIndex
的值越大,层级越高。
Stack() {
Row()
.width(150)
.height(150)
.backgroundColor('#255FA7') //蓝色
.shadow({ radius: 50 })
.zIndex(3)
Row()
.width(200)
.height(200)
.backgroundColor('#E66826') //橙色
.shadow({ radius: 50 })
.zIndex(2)
Row()
.width(250)
.height(250)
.backgroundColor('#107B02') //绿色
.shadow({ radius: 50 })
.zIndex(1)
}.width(300)
.height(300)
.backgroundColor('#E5E5E5') //灰色
3.3.2 子组件精确定位
Stack
容器的子组件可使用position()
方法进行更精确的定位,该方法可设置子组件左上角相对于Stack
容器左上角的偏移量,具体效果如下
Stack() {
Image($r('app.media.img_avatar'))
.width('100%')
.height('100%')
Image($r('app.media.icon_v'))
.width(60)
.height(60)
.position({ x: 140, y: 140 })
}
.width(200)
.height(200)
四、弹性布局(Flex)
4.1 概述
弹性布局(Flex)
的效果类似于线性布局(Column/Row)
,也会使子元素呈线性排列,但是弹性布局在子元素的排列、对齐和剩余空间的分配等方面更加灵活。
4.2 参数
Flex组件的参数定义如下,下面逐一介绍每个属性
Flex(value?: { direction?: FlexDirection, justifyContent?: FlexAlign, alignItems?: ItemAlign, wrap?: FlexWrap, alignContent?: FlexAlign })
4.2.1 布局方向(dirction)
dirction
用于设置Flex容器的布局方向,即子元素的排列方向,其类型FlexDirection
为枚举类型,可选的枚举值如下
名称 | Row | RowReverse | Column | ColumnReverse |
---|---|---|---|---|
描述 | 水平方向,元素从左到右排列 | 水平方向,元素从右到左排列 | 垂直方向,元素从上到下排列 | 垂直方向,元素从下到上排列 |
效果 |
Flex
容器中也有主轴和交叉轴两个概念,其中主轴方向与direction
一致,交叉轴与主轴垂直,具体方向如下
direction | Row | RowReverse | Column | ColumnReverse |
---|---|---|---|---|
主轴和交叉轴 |
4.2.2 主轴排列方式(justifyContent)
justifyContent
参数的作用同Column/Row
容器的justifyContent()
完全相同,也是用于设置子元素在主轴方向的排列方式,其类型同样为FlexAlign
,可选的枚举值如下
名称 | 描述 | 效果(以direction=Row为例) |
---|---|---|
Start | 分布在起始端 | |
Center | 居中 | |
End | 分布在结束端 | |
SpaceBetween | 均匀分布,首尾两项两端对齐,中间元素等间距分布 | |
SpaceAround | 均匀分布,所有子元素两侧都留有相同的空间 | |
SpaceEvenly | 均匀分布,所有子元素之间以及首尾两元素到两端的距离都相等 |
4.2.3 交叉轴对齐方式(alignItems)
alignItems
参数的作用同Column/Row
容器的alignItems()
相同,也是用于设置子元素在交叉轴的对齐方式。但该参数的类型与Column/Row
容器的alignItems()
方法不同,为ItemAlign
,可选的枚举值有
名称 | 描述 | 效果(以direction=Row为例) |
---|---|---|
Start | 启始端对齐 | |
Center | 居中对齐 | |
End | 结束端对齐 | |
Stretch | 拉伸到容器尺寸 | |
BaseLine | 沿文本基线对齐(限于Text文本组件) |
4.2.4 布局换行(列)(wrap)
默认情况下,Flex
容器的子组件,都排在一条线(主轴)上。当子组件在主轴方向的尺寸之和大于Flex容器时,为适应容器尺寸,所有子组件的尺寸都会自动收缩。如果需要保持子组件的尺寸不收缩,也可选择令子组件换行(列)显示。wrap
属性的作用就是控制如何换行,该属性的类型FlexWrap
为枚举类型,可选的枚举值如下
名称 | 描述 | 效果(以direction=Row为例) |
---|---|---|
NoWrap | 不换行 | |
Wrap | 换行,每一行子组件按照主轴方向排列 | |
WrapReverse | 换行,每一行子元素按照主轴反方向排列 |
4.2.5 交叉轴多行排列方式(alignContent)
当Flex
容器中包含多行(列)时,可使用alignContent
设置多行在交叉轴的排列方式,该属性的类型为FlexAlign
,可选的枚举值如下
名称 | Start | Center | End | SpaceBetween | SpaceAround | SpaceEvenly |
---|---|---|---|---|---|---|
描述 | 分布在起始端 | 居中 | 分布在终点端 | 均匀分布,首尾两项两端对齐,中间元素等间距分布 | 均匀分布,所有子元素两侧都留有相同的空间 | 均匀分布,所有子元素之间以及首尾两元素到两端的距离都相等 |
效果(以direction=Row为例) |
4.3 子组件常用属性
4.3.1 交叉轴对齐(alignSelf)
Flex
容器的子组件可以使用alignSelf()
方法单独设置自己的交叉轴对齐方式,并且其优先级高于Flex
容器alignItems
。具体效果如下
说明:alignSelf()
的参数类型和alignItems()
相同,均为ItemAlign
枚举类型,且各枚举值的含义也完全相同。
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start }) {
Text('1')
.width(100)
.height(100)
.itemTextStyle()
Text('2')
.width(100)
.height(200)
.itemTextStyle()
Text('3')
.width(100)
.height(150)
.itemTextStyle()
.alignSelf(ItemAlign.End) //单独设置交叉轴对齐方式
}.height(300)
.width('95%')
.flexStyle()
4.3.2 自适应伸缩
弹性布局的显著特点之一是子组件沿主轴方向的尺寸具有弹性,即子组件的大小能够随着Flex容器尺寸的变化而自动伸缩。这种弹性特性使得Flex布局能够使子组件更灵活地适应不同的屏幕尺寸和设备。和自适应伸缩的相关的属性有flexShrink
、flexGrow
和flexBasis
,下面逐一介绍
flexShrink
flexShrink
用于设置父容器空间不足时,子组件的压缩比例,尺寸的具体计算逻辑如下//Flex容器主轴尺寸为240,子组件主轴尺寸之和为100*3=300 Flex() { //尺寸=100 Text('1') .width(100) .height(100) .flexShrink(0) //不压缩 //主轴尺寸=100-(300-240)*(1/3)=80 Text('2') .width(100) .height(100) .flexShrink(1) //压缩比例为1 //主轴尺寸=100-(300-240)*(2/3)=60 Text('3') .width(100) .height(100) .flexShrink(2) //压缩比例为2 }.height(150) .width(240)
flexGrow
flexGrow
用于设置父容器空间充足时,组件瓜分剩余空间的比例,尺寸的具体计算逻辑如下Flex() { //尺寸=100 Text('1') .width(100) .height(100) .flexGrow(0) //不拉伸 //主轴尺寸=100+(360-300)*(1/3)=120 Text('2') .width(100) .height(100) .flexGrow(1) //拉伸比例为1 //主轴尺寸=100+(360-300)*(2/3)=140 Text('3') .width(100) .height(100) .flexGrow(2) //拉伸比例为2 }.height(150) .width(360)
- flexBasis
flexBasis
用于设置子组件沿主轴方向的尺寸,相当于width
或者height
的作用。若设置了flexBasis
,则以flexBasis
为准,否则以widht
或者height
为准。
五、网格布局(Grid)
5.1 概述
网格布局(Grid)是一种强大的布局方案,它将页面划分为行和列组成的网格,然后将页面内容在二维网格中进行自由的定位,以下效果都可通过网格布局实现
网格布局的容器组件为 Grid,子组件为 GridItem,具体语法如下
Grid() {
GridItem() {
Text('GridItem')
}
GridItem() {
Text('GridItem')
}
GridItem() {
Text('GridItem')
}
GridItem() {
Text('GridItem')
}
......
}
5.2 常用属性
5.2.1 划分网格
Grid
组件支持自定义行数和列数以及每行和每列的尺寸大小,上述内容需要使用rowsTemplate()
方法和columnsTemplate()
方法进行设置,具体用法如下
Grid() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9], (item) => {
GridItem() {
Text(item.toString())
.itemTextStyle()
}
})
}
.width(320)
.height(240)
.rowsTemplate('1fr 1fr 1fr')
.columnsTemplate('1fr 2fr 1fr')
.gridStyle()
说明:
fr为 fraction(比例、分数) 的缩写。fr的个数表示网格布局的行数或列数,fr前面的数值大小,表示该行或列的尺寸占比。
5.2.2 子组件所占行列数
GridItem组件支持横跨几行或者几列,如下图所示
可以使用columnStart()
、columnEnd()
、rowStart()
和rowEnd()
方法设置 GridItem
组件所占的单元格,其中rowStart
和rowEnd
属性表示当前子组件的起始行号和终点行号,columnStart
和columnEnd
属性表示指定当前子组件的起始列号和终点列号。
说明:
Grid容器中的行号和列号均从0开始。
Grid() {
GridItem() {
Text('1')
.itemTextStyle()
}.rowStart(0).rowEnd(1).columnStart(0).columnEnd(1)
GridItem() {
Text('2')
.itemTextStyle()
}
GridItem() {
Text('3')
.itemTextStyle()
}
GridItem() {
Text('4')
.itemTextStyle()
}
GridItem() {
Text('5')
.itemTextStyle()
}.columnStart(1).columnEnd(2)
}
.width(320)
.height(240)
.rowsTemplate('1fr 1fr 1fr')
.columnsTemplate('1fr 2fr 1fr')
.gridStyle()
5.2.3 行列间距
使用rowsGap()
和columnsGap()
属性,可以控制行列间距,具体用法如下
Grid() {
......
}
.columnsGap(20)
.rowsGap(20)
六、列表布局(List)
6.1 概述
List
容器的子组件为ListItem
或者ListItemGroup
,其中,ListItem
表示单个列表项,ListItemGroup
用于列表数据的分组展示,其子组件也是ListItem
,具体用法如下
列表项
List() { // 列表项 ListItem() {......} ListItem() {......} ListItem() {......} ListItem() {......} ListItem() {......} ListItem() {......} ListItem() {......} ListItem() {......} ListItem() {......} ListItem() {......} ListItem() {......} ListItem() {......} }
列表组
List() { // 列表组 ListItemGroup(){ //列表项 ListItem(){......} ListItem(){......} } ListItemGroup(){ ListItem(){......} ListItem(){......} } ListItemGroup(){ ListItem(){......} ListItem(){......} } }
6.2 参数
List 组件的参数定义如下,下面逐一介绍每个参数
List(value?:{space?: number | string, scroller?: Scroller})
6.2.1 列表项间距
space
参数用于设置列表项的间距
6.2.2 列表滚动控制器
scroller
参数用于绑定列表滚动控制器(Scroller)
,Scroller
可以控制列表的滚动,例如令列表返回顶部
6.3 常用属性
6.3.1 主轴方向
使用listDirection()
方法可以设置列表的主轴方向(即列表的排列和滚动方向),其参数类型为枚举类型Axis
,可选的枚举值如下
名称 | 描述 | 效果 |
---|---|---|
Axis.Vertical | 纵向 | |
Axis.Horizontal | 横向 |
6.3.2 交叉轴对齐方式
使用alignListItem()
方法可以设置子组件在交叉轴方向的对齐方式,其参数类型为枚举类型ListItemAlign
,可选的枚举值有
名称 | ListItemAlign.Start | ListItemAlign.Center | ListItemAlign.End |
---|---|---|---|
描述 | 交叉轴起始端对齐 | 交叉轴居中对齐 | 交叉轴末端对齐 |
效果(以listDirection=Axis.Vertical为例) |
6.3.3 元素分割线
使用divider()
属性可设置列表元素分割线样式,该方法的参数定义如下
divider(value: {strokeWidth: Length, color?: ResourceColor, startMargin?: Length, endMargin?: Length})
各参数的含义如下
参数 | 含义 |
---|---|
strokeWidth | 分割线线宽 |
color | 分割线颜色 |
startMargin | 分割线起始端到列表侧边距离(如下图所示) |
endMargin | 分割线末端到列表侧边距离(如下图所示) |
6.3.4 滚动条样式
使用scrollBar()
方法可以设置滚动条状态,该方法的参数类型为枚举类型BarState,可选的枚举值如下
名称 | 描述 |
---|---|
BarState.Off | 不显示 |
BarState.On | 常驻显示 |
BarState.Auto | 按需显示(触摸时显示,2s后消失) |
6.3.5 其余功能
上述只是List列表布局最为常用的一些功能,其余功能可参考官方文档。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。