通过之前的学习,想必大家对如何通过Row和Column来构建一个最基础的页面已经有了一个初步的掌握,接下来,笔者将会介绍更多的页面布局,来将我们的页面变得更加丰富精彩。在本篇博客中,笔者将会介绍Grid/GridItem(网格布局),尽可能的详细的解释该布局的用法以及在实际开发过程中一些小技巧的使用。
Grid
首先我们来对Grid进行一个初步的认识:
网格布局(Grid)是由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。网格布局具有较强的页面均分能力,子组件占比控制能力,是一种重要自适应布局,其使用场景有九宫格图片展示、日历、计算器等。
上面的内容是官方给出的对Grid的文字定义,不难看出,网格布局在特定场景(例如日历、计算器等)下是有较大优势的,它可以轻松的将页面进行均分,大大减少代码量,提高编码效率,而且做出来的页面会更加简洁美观。我们用图片来解释会更加明了,如下图:
在这张图片中,Grid网格布局通过其子组件GridItem将整个页面划分为一个九宫格的布局形式,我们可以在每一个GridItem再进行布局,从而实现每一个GridItem都能实现其独特的功能,大大提升了页面的美观以及实用性,需要注意的是,Grid的子组件只能是GridItem,所以,这两者一般是组合出现使用的。
如图便是一个计算器的页面,这个页面便是使用Grid的一个典型例子,在每一个GridItem中放入一个Button按钮,并赋予他们各自的功能,最终组成整个计算器系统的页面。
又例如此图,软件中它将不同的餐品放在一张张单独的卡片中,这也是可以通过Grid来进行布局的,这样的布局使得整个页面清晰明了,有利于顾客更好地选餐。总之这是一个应用场景非常广的布局方式,接下来,笔者将详细讲解一下该布局的写法。
排列方式
由上面两个例子我们不难发现,Grid可以自由的设置其子组件GridItem的大小、长宽比以及数量,那么我们该如何来设置它呢?
Grid组件提供了rowsTemplate和columnsTemplate属性用于设置网格布局行列数量与尺寸占比。
rowsTemplate和columnsTemplate属性值是一个由多个空格和’数字+fr’间隔拼接的字符串,fr的个数即网格布局的行或列数,fr前面的数值大小,用于计算该行或列在网格布局宽度上的占比,最终决定该行或列宽度。
columnsTemplate的属性描述:
设置当前网格布局列的数量或最小列宽值,不设置时默认1列。
例如, ‘1fr 1fr 2fr’ 是将父组件分3列,将父组件允许的宽分为4等份,第一列占1份,第二列占1份,第三列占2份。
columnsTemplate(‘repeat(auto-fit, track-size)’)是设置最小列宽值为track-size,自动计算列数和实际列宽。
columnsTemplate(‘repeat(auto-fill, track-size)’)是设置固定列宽值为track-size,自动计算列数。
其中repeat、auto-fit、auto-fill为关键字。track-size为列宽,支持的单位包括px、vp、%或有效数字,track-size至少包括一个有效列宽。
说明:
设置为’0fr’时,该列的列宽为0,不显示GridItem。设置为其他非法值时,GridItem显示为固定1列。
rowsTemplate的属性描述:
设置当前网格布局行的数量或最小行高值,不设置时默认1行。
例如, ‘1fr 1fr 2fr’是将父组件分三行,将父组件允许的高分为4等份,第一行占1份,第二行占一份,第三行占2份。
rowsTemplate(‘repeat(auto-fit, track-size)’)是设置最小行高值为track-size,自动计算行数和实际行高。
rowsTemplate(‘repeat(auto-fill, track-size)’)是设置固定行高值为track-size,自动计算行数。
其中repeat、auto-fit、auto-fill为关键字。track-size为行高,支持的单位包括px、vp、%或有效数字,track-size至少包括一个有效行高。
说明:
设置为’0fr’,则这一行的行宽为0,这一行GridItem不显示。设置为其他非法值,按固定1行处理。
通过下面这张图可以看得更加明了一点。
上图使用代码演示就是这样:
Grid() {
...
}
.rowsTemplate('1fr 1fr 1fr')
.columnsTemplate('1fr 2fr 1fr')
这段代码通过rowsTemplate将整个页面的分为了3行,每一行都为一等份 [ 使用(‘1fr 1fr 1fr’)表示 ] ,再在此基础上分出了3列,其中两边为一份,中间为两份 [ 使用(‘1fr 2fr 1fr’)表示 ],这样切割下来,便成为了如上图那样的网格型布局了.
这样一个页面就有了一个初步的模型,接下来,我们以计算器为例,向GridItem中填充一些简单的内容:
通常的,我们只要向GridItem中加入Text组件,就可以实现文字的填充:
GridItem() {
Text('1')
...
}
但是在下图的这种情况中,我们还要使用到columnStart和columnEnd这两个属性。
这两个属性表示指定当前元素的起始列号和终点列号,例如,上图中的“0”按钮,它与其他按钮不同的是,它横跨了第一列和第二列,所以在这个按钮中填充文本时,就要加上起始和终点列号,代码如下:
GridItem() {
Text("0")
...
}
.columnStart(1)
.columnEnd(2)//colum表示列,该按钮横跨第一列到第二列,所以起始Start为1,终点End为2
再例如上图中的“=”按钮,代码如下:
GridItem() {
Text("=")
...
}
.rowStart(5)
.rowEnd(6)//row表示行,该按钮横跨第五列到第六列,所以起始Start为5,终点End为6
上面的所有情况都是在已经设置好行和列的数量及占比的前提下进行的,如果我们直接让GridItem去自行排列,则又是使用另外一种方法。
设置主轴方向
这里我们就需要要确定一个页面的主轴,主轴是水平方向还是垂直方向决定了接下来GridItem按什么方式排列,这里会引入Grid的一个新的属性:layoutDirection,该属性的参数是GridDirection,通过这个参数我们可以选择该Grid的主轴方向,如图:
从图中我们可以看到,一共有4个选项,分别是Row、Column、RowReverse、ColumnReverse,前面两个分别代表以水平正向排列和垂直正向排列(从左往右,从上往下),而后面两个则是分别代表水平反向排列和垂直反向排列(从右往左,从下往上),这里我们还需要引入一个新的属性:maxCount和minCount,这两个属性代表着主轴上能排列的最大和最小的GridItem数量,例如
Grid() {
...
}
.layoutDirection(GridDirection.Row)//代表主轴方向为水平方向,即从左往右排列
.maxCount(3)//代表水平方向最多有3个GridItem,多于3个就要向下换行
如图:
同理,将主轴换为垂直方向。
Grid() {
...
}
.layoutDirection(GridDirection.Column)//代表主轴方向为垂直方向,即从上往下排列
.maxCount(3)//代表垂直方向最多有3个GridItem,多于3个就要向右换行
如图:
设置行列间距
接下来,我们要来了解一下如何控制各个GridItem之间的距离,将页面做得更加美观。
设置行列间距只需要用到两个简单的属性:rowsGap和columnsGap,我们直接进入代码演示:
Grid() {
...
}
.columnsGap(10)
.rowsGap(15)
我们只需要根据页面的布局,更改这两个属性中的数据,就可以自由的调整各个元素之间的距离。