ArkUI框架之基础布局(二)
本文介绍了ArkUI中的两种基础布局:相对布局(RelativeContainer)和滚动容器(Scroll)。相对布局通过锚点和对齐方式实现子组件相对于父容器或兄弟组件的定位,支持位置偏移调整。滚动容器(Scroll)用于内容超出容器尺寸时的滚动显示,需注意其只能包含一个子组件且子组件尺寸需大于容器。文章通过代码示例和图示展示了两种布局的核心用法和注意事项。
基础布局
1.相对布局 (RelativeContainer)
1.1 基本概念
RelativeContainer为相对布局的容器,支持容器内部的子元素设置相对位置关系,适用于界面复杂场景的情况。
使用相对布局,需要搞清楚下面两个概念
● 锚点:通过锚点设置当前元素基于哪个元素确定位置。
● 对齐方式:通过对齐方式,设置当前元素是基于锚点的上中下对齐,还是基于锚点的左中右对齐。
如下图所示,红色方块Row相对于父容器RelativeContainer的位置可以通过指定的锚点对其方式来设定。
左图:
● Row的左边框与RelativeContainer的左边框对齐,此时RelativeContainer的左边框就是一个锚点
● Row的上边框与RelativeContainer的上边框对齐,此时RelativeContainer的上边框就是一个锚点
右图:
● Row的下边框与RelativeContainer的下边框对齐,此时RelativeContainer的下边框就是一个锚点
● Row的右边框与RelativeContainer的有边框对齐,此时RelativeContainer的有边框就是一个锚点

1.2 相对父容器定位
如下图所示,最外层蓝色的方框是一个RelativeContainer,然后相对于该容器,放置4个带颜色的小方块在不同的位置。
如图:第一个绿色小方块相对于父容器的对齐方式,其他组件依此内推。
完整代码如下:RelativeContainer容器组件的id默认为"container",每个组件的相对位置都是以
"container"为锚点
@Entry
@Component
struct Index {
build() {
Row() {
RelativeContainer() {
Row()
.id("row1")
.width(100)
.height(100)
.backgroundColor(Color.Green)
.alignRules({
top: { anchor: "__container__", align: VerticalAlign.Top },
left: { anchor: "__container__", align: HorizontalAlign.Start }
})
Row()
.id("row2")
.width(100)
.height(100)
.backgroundColor(Color.Brown)
.alignRules({
top: { anchor: "__container__", align: VerticalAlign.Top },
right: { anchor: "__container__", align: HorizontalAlign.End }
})
Row()
.id("row3")
.width(100)
.height(100)
.backgroundColor(Color.Orange)
.alignRules({
bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
left: { anchor: "__container__", align: HorizontalAlign.Start }
})
Row()
.id("row4")
.width(100)
.height(100)
.backgroundColor(Color.Blue)
.alignRules({
bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
right: { anchor: "__container__", align: HorizontalAlign.End }
})
})
}
.width(300).height(300)
.margin({ left: 50 })
.border({ width: 2, color: "#6699FF" })
}
.height('100%')
}
}
1.3 子组件位置偏移
接下来我想在蓝色方框的中间位置放置一个红色方块,按照前面学习的对齐方式采用水平居中、垂直居中对齐。
● 理想效果是这样的

@Entry
@Component
struct Index {
build() {
Row() {
RelativeContainer() {
//....
//想要居中对齐的组件
Row()
.id("row5")
.width(100)
.height(100)
.backgroundColor(Color.Red)
.alignRules({
//上边框与父组件中线居中
top: { anchor: "__container__", align: VerticalAlign.Center },
//左边框与父组件中线居中
left: { anchor: "__container__", align: HorizontalAlign.Center }
})
}
.width(300).height(300)
.border({ width: 2, color: "#6699FF" })
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
- 但是实际效果是这样的

此时需要对子组件进行位置偏移,使用offset属性进行位置偏移。 注意:坐标轴的方向,x轴正方向向右,y轴正方向向下。
哈哈,效果达到了
1.4 相对兄弟组件定位
如果RelativeContainer父容器看作是父亲,那么里面的子组件就是儿子,同级别的多个子组件就是兄弟关系。
注意:相对于兄弟组件定位,必须给兄弟组件设置一个id值,否则找不到兄弟组件,会导致组件显示不了。
RelativeContainer() {
Row().id('row6').width(100).height(100).backgroundColor(Color.Green)
Row().id('row7').width(100).height(100).backgroundColor(Color.Brown)
.alignRules({
left: {anchor:'row6',align:HorizontalAlign.End},
top:{anchor: 'row6',align:VerticalAlign.Bottom}
})
}.width(300).height(300)
.border({ width: 2, color: "#6699FF" })
2.滚动容器(Scroll)
2.1 核心用法
在ArkUI中,使用Scroll表示可滚动的容器组件,当子组件的布局尺寸超过父组件的尺寸时,内容可以滚动。
📢 注意:Scorll使用时有以下两个注意点
- Scroll 有且只能包含一个子组件
- Scroll 子组件的布局尺寸大于父组件的尺寸时,才可以滚动。

代码展示
@Entry
@Component
struct Index {
scroller:Scroller = new Scroller()
build() {
Column() {
Row()
.width('100%')
.height(50)
.backgroundColor(Color.Red)
Scroll(){
Column({space:10}) {
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
}
.width('100%')
.backgroundColor(Color.Orange)
}.layoutWeight(1)
.scrollBar(BarState.On) //打开滚动条
.scrollable(ScrollDirection.Vertical) //滚动方向
.scrollBarWidth(20) //滚动条宽度
.scrollBarColor(Color.Red) //滚动条颜色
Row()
.width('100%')
.height(50)
.backgroundColor(Color.Blue)
}
.justifyContent(FlexAlign.SpaceBetween)
.width('100%')
.height('100%')
}
}
3. 栅格布局(GridRow)
3.1 基本概念
栅格布局可以在不同的设备上自适应排版,使得页面布局更加灵活和适应性更强。当页面元素的数量超出了一行或一列的容量时,他们会自动换到下一行或下一列。
GridRow为栅格容器组件,需与栅格子组件GridCol在栅格布局场景中联合使用。栅格系统以屏幕宽度为依据,把屏幕分为若干个列,每一个栅格子可以横跨指定的列从而完成组件的定位和布局。
3.2 栅格系统的总列数
栅格系统的总列数可以使用默认值(12列),也可以自己指定列数,还可以根据屏幕的宽度动态调整列数。
3.2.1 默认栅格列数

@Entry
@Component
struct Index {
build() {
GridRow() {
GridCol() {
Row() {
Text('1')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('2')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('3')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('4')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('5')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('6')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('7')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('8')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('9')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('10')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('11')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
GridCol() {
Row() {
Text('12')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
}.height(300).backgroundColor(Color.Pink)
}
}
3.2.2 指定栅格列数
通过GridRow的{columns:6}参数可以指定栅格总列数。比如下面案例中,栅格总列数为6,一共12个栅格子,那么一行就是6个,超过一行的部分自动换行。
@Entry
@Component
struct Index {
build() {
GridRow({ columns: 6 }) {
GridCol() {
Row() {
Text('1')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
//...中间省略了10个栅格子GridCol(),包括上下两个栅格子,一共12个栅格子
GridCol() {
Row() {
Text('12')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
}.height(300).backgroundColor(Color.Pink)
}
}
3.2.3 动态调整列数
为了适应不同屏幕尺寸下的布局,栅格系统的总列数可以根据不同的屏幕尺寸动态调整。
要实现动态调整列数,这里需要引入一个概念叫做栅格系统断点。
栅格系统断点
是指在响应式设计中,用于控制页面布局变化的一系列特定数值点。这些数值点基于设备的屏幕宽度来设定,当屏幕宽度达到或超过某个断点时,页面的布局或组件的排列方式会相应地发生调整,以适应不同尺寸的屏幕。
如下图所示:把这条直线看作屏幕的宽度,上面的5个数值点就是断点,5个断点把屏幕宽度分为6个区间,对应6种设备宽度。(当然这个断点的数值也是可以自己设定的)

不同屏幕尺寸的设备,就是依靠断点进行区分的,如下表
如下代码:根据断点设备设置栅格总列数
GridRow({
//设置对应断点设备的总列数
columns: {
xs: 3, //最小宽度型设备3列
sm: 6, //小宽度设备6列
md: 8, //中型宽度设备8列
lg: 12 //大型宽度设备12列
},
//设置断点
breakpoints: {
value: ['320vp', '520vp', '840vp', '1080vp', '1920vp']
}
}){
//GridCol栅格子组件....
}
3.3 栅格子占用列数
通过设置GridCol传参{span:3}来设置栅格子占用的列数。比如我们想要的效果如下。
@Entry
@Component
struct Index {
build() {
GridRow({columns: 6) {
//第1个栅格
GridCol({ span: 3 }) {
Row() {
Text('1')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
//...中间省略了第2,3,4个栅格子
//第5个栅格子
GridCol({span:6}) {
Row() {
Text('5')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
//...中间省略了第6个栅格子
//第7个栅格子
GridCol({ span: 4 }) {
Row() {
Text('7')
}
.width('100%')
.height(50)
.border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
.justifyContent(FlexAlign.Center)
}
//...这里省略了第8,9,10,11,12个栅格子
}.height(300).backgroundColor(Color.Pink)
}
}
3.4 栅格间距
通过GridRow的{gutter: 10} 参数可以调整栅格子之间的间距,默认为0。
GridRow({
columns: 6
gutter: 10
}){
//GridCol栅格子
}

4.Grid 网格布局
ArkUI提供了Grid容器组件和子组件GridItem,用于构建网格布局。Grid用于设置网格布局相关参数,GridItem定义子组件相关特征。
4.1 基本使用
如同所示,显示一个3行3列的网格,每一个单元格中显示一个数字。
@Entry
@Component
struct GridPage1 {
@State numbers: number[] = []
onPageShow(): void {
for (let index = 0; index < 10; index++) {
this.numbers.push(index)
}
}
build() {
Column() {
Grid() {
ForEach(this.numbers, (item: number, index: number) => {
GridItem() {
Text(`${item}`).textAlign(TextAlign.Center).width("100%").height(50).backgroundColor(Color.Yellow)
}
})
}
.width("100%")
.height(200) //Grid 如果没有设置宽高,则自适应父组件宽高
.backgroundColor(Color.Pink)
.columnsTemplate("1fr 1fr 1fr") //列数
.rowsTemplate("1fr 1fr 1fr") //行数
.rowsGap(10) //行间距
.columnsGap(10) //列间距
}
.width("100%")
.height("100%")
}
}
更多推荐


所有评论(0)