0 概述
说到线性布局,不知道做过 Android 开发的朋友是不是跟笔者一样,第一反应就是"这不就是 Android 中的 LinearLayout 么"(脑补一个抠鼻表情)
鸿蒙在ArkUI中,将这个 LinearLayout 拆分成了Row
、Column
,从名字上也能猜出来这俩人中,Row
负责横向的线性布局,也就是相当于 LinearLayout 的 orientation="horizontal";Column
负责竖向的线性布局,相当于 LinearLayout 的 orientation="vertical"。
1 基本概念
鸿蒙对于线性布局,引入了 主轴、交叉轴的概念
- 主轴:线性布局容器在布局方向上的轴线,子元素默认沿主轴排列。
Row
容器主轴为水平 方向,Column
容器主轴为垂直方向。 - 交叉轴:垂直于主轴方向的轴线。
Row
容器交叉轴为垂直 方向,Column
容器交叉轴为水平方向。
简单来说
- 主轴:与线性容器中子组件的排列方向一致
- 交叉轴:与线性容器中子组件的排列方向垂直
2 基本用法
其实Column
和Row
的用法差不多,区别就是一个竖向、一个横向,所以本文主要以Column
的用法为主,Row
的用法跟Column
类似,可以看下参考资料中的链接,笔者就不再做过多的介绍了。我们先看个Column
的效果图
上图是在Column
中添加了三个Text组件,当然为了便于区分,给每个Text组件都增加了背景色,后面会详细介绍Text组件,这里就先不赘述了。这个页面的代码如下:
TypeScript
@Entry
@Component
struct Index {
build() {
Column() {
Text('我是孙小胖児')
.width(160)
.height(30)
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Brown)
Text('我是孙小胖児')
.width(160)
.height(30)
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Gray)
Text('我是孙小胖児')
.width(160)
.height(30)
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Blue)
}
.height('100%')
.width('100%')
.padding(16)
.backgroundColor(0xCCCCCC)
}
}
上图这段代码中可以看到,第31~34行,是针对Column
的设置,width、height、padding、backgroundcolor,这四个属性看着是不是很眼熟
width、height,这两个属性,设置组件的宽高,当然了,因为在这段代码中,Column
作为根容器,它的宽高肯定是要填满整个屏幕的,因此也就写了100% ,这里需要注意的是,这个100%是以字符串的形式当作参数的,除了100%,还可以写具体的数值,比如100,这个就表示是100vp,这个vp
是鸿蒙的单位,类似于Android的dp。
padding
如果只写一个数字,那代表左、上、右、下的padding间距都是16vp,当然也有单独控制的写法,如下所示:
TypeScript
.padding({
top: 16,
left: 32,
right: 32,
bottom: 16
})
当然了,margin
跟padding
一样,也有这两种设置方式,只不过控制的间距是不一样的,padding
控制的是组件内部的间距,margin
控制的是组件与组件之间的间距。
不过,如果Column / Row 他们的子组件的间距是固定的,那么可以用下面这个方式来设置:
TypeScript
@Entry
@Component
struct Index {
build() {
Column({space: 20}) { // 通过 space,来设置子组件的间距
Text('我是孙小胖児')
.width(160)
.height(30)
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Brown)
Text('我是孙小胖児')
.width(160)
.height(30)
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Gray)
Text('我是孙小胖児')
.width(160)
.height(30)
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Blue)
}
.height('100%')
.width('100%')
.padding(16)
.backgroundColor(0xCCCCCC)
}
}
运行后的效果如下:
3 子组件的对齐方式
Clomun
和Row
这两个线性容器的子组件对齐方式,主要是针对交叉轴说的。对于Column
组件来说交叉轴就是水平方向,自然的对于Row
组件来说交叉轴就是垂直方向。Column
的交叉轴的对齐方式有三种,分别是:Start、Center、End;Row
的交叉轴的对齐方式也有三种,分别是:Top、Center、Bottom。属性都是alignItems,只不过参数一个是HorizontalAlign ,一个是VerticalAlign。
Column
Row
Column
的交叉轴对齐的具体效果如下:
- HorizontalAlign.Start
- HorizontalAlign.Center
- HorizontalAlign.End
Row
的交叉轴对齐的具体效果如下:
- VerticalAlign.Top
- VerticalAlign.Center
- VerticalAlign.Bottom
4 子组件的摆放方式
子组件的摆放方式,是针对主轴来说的。前面说过主轴就是线性容器中子组件的排列方向,所以Column
的主轴就是垂直方向,Row
的主轴就是水平方向。二者设置主轴上子组件的摆放方法,也是个通用属性:.justifyContent()
Column
Row
从上面个两张图可以看到,不论是Column
还是Row
,这个justifyContent属性的参数都是一模一样的
按照惯例,我们还是先看看Column
主轴上的对齐效果,为了节省篇幅,把这六个对齐方式拼在一起了
Column
Row
从图中可以看出,FlexAlign.Start 、FlexAlign.Center 、FlexAlign.End 这三种对齐方式对于Column
来说分别是:居顶、居中、居底摆放;对于Row
来说分别是:居左、居中、居右摆放。
FlexAlign.SpaceBetween 、FlexAlign.SpaceAround 、FlexAlign.SpaceEvenly 这三种摆放方式,是子组件对于主轴上的空间的分配,从图中可以看出,这三种空间的分配,对于子组件来说,所有子组件的间距是相等的,唯一的区别在于头、尾两个子组件与父容器的间距不同,图中箭头所指的线段,具体的区别为:
- FlexAlign.SpaceBetween:头、尾两个子组件与父容器的间距为0。
- FlexAlign.SpaceAround:头、尾两个子组件与父容器的间距是子组件之间间距的一半
- FlexAlign.SpaceEvenly:头、尾两个子组件与父容器的间距与子组件之间的间距相同
5 三种自适应布局
在鸿蒙的官方开发指南中,线性布局这一章节的最后,是三种自适应的布局,分别是:自适应拉伸、自适应缩放、自适应延伸。咱们分别看看这三个都是什么新鲜玩意儿。
5.1 自适应拉伸
自适应拉伸,按照官方文档的说法,就是在主轴方向的子组件之间放一个名为Blank
的组件,从名字上也猜出来,这玩意儿就是个空白组件。使用起来也很简单,就直接写个Blank()
就完事了(下面这段代码中的第15行)
TypeScript
@Entry
@Component
struct Index {
build() {
Row() {
Text('我是孙小胖児')
.width(80)
.height(50)
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Brown)
Blank()
Text('我是孙小胖児')
.width(80)
.height(50)
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Gray)
}
.height('100%')
.width('100%')
}
}
运行起来一看效果,我人麻了
这玩意儿跟下面这代码有啥区别??
TypeScript
Row() {
}
.justifyContent(FlexAlign.SpaceBetween)
实现的效果不都一样,笔者想了几个小时小时没想明白。如果有哪位朋友理解了这个Blank
的奥义,还请在评论区赐教(抱拳了.jpg)
5.2 自适应缩放
开始看到这个标题的时候,有点没反应过来,后来看了下具体的代码,发现指的是layoutWeight
这个属性,瞬间就明白了,毕竟这个属性在Android中也有,虽然我用的不太多吧😂好了,不废话了,直接上代码
TypeScript
@Entry
@Component
struct Index {
build() {
Column() {
Text('我是孙小胖児\n layoutWeight(1)')
.layoutWeight(1)
.width('100%')
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Brown)
Text('我是孙小胖児\n layoutWeight(2)')
.layoutWeight(2)
.width('100%')
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Gray)
Text('我是孙小胖児\n layoutWeight(3)')
.layoutWeight(3)
.width('100%')
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Blue)
}
.height('100%')
.width('100%')
}
}
上面的代码运行后的效果如下:
对于Row
这个容器也是一样
TypeScript
@Entry
@Component
struct Index {
build() {
Row() {
Text('我是孙小胖児 layoutWeight(1)')
.layoutWeight(1)
.height('100%')
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Brown)
Text('我是孙小胖児 layoutWeight(2)')
.layoutWeight(2)
.height('100%')
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Gray)
Text('我是孙小胖児 layoutWeight(3)')
.layoutWeight(3)
.height('100%')
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Blue)
}
.height('100%')
.height('100%')
}
}
提示一下:在
Column
中使用 layoutWeight 的时候,子组件不需要设置高度,相应的,在Row
中使用 layoutWeight 的时候,子组件不需要设置宽度
除了 layoutWeight 这个属性可以使子组件自适应缩放以外,还可以在设置width 、height这两个属性的时候,直接写百分比。
TypeScript
@Entry
@Component
struct Index {
build() {
Column() {
Text('我是孙小胖児 height(\'20%\')')
.height('20%')
.width('100%')
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Brown)
Text('我是孙小胖児 height(\'30%\')')
.height('30%')
.width('100%')
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Gray)
Text('我是孙小胖児 height(\'50%\')')
.height('50%')
.width('100%')
.fontSize(20)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(Color.Blue)
}
.width('100%')
.width('100%')
}
}
上面是在Column
中用百分比来设置with 、height 的方式实现自适应缩放,Row
容器的用法类似,就不再赘述了。
5.3 自适应延伸
这个自适应延伸,实际上就是使用Scroll
组件,或者List
组件来实现页面的滚动效果,当然了除非是列表页面,否则大部分情况下都是使用Scroll
实现页面的滚动效果,后面会单独写Scroll
组件,就不再赘述了。
本文正在参加华为鸿蒙有奖征文征文活动