• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 网格布局
2
3网格布局(GridLayout)是自适应布局中一种重要的布局,具备较强的页面均分能力,子组件占比控制能力。
4通过[Grid](../reference/arkui-ts/ts-container-grid.md)容器组件和子组件[GridItem](../reference/arkui-ts/ts-container-griditem.md)实现,
5Grid用于设置网格布局相关参数,GridItem定义子组件相关特征。优势如下:
6
71. 容器组件尺寸发生变化时,所有子组件以及间距等比例调整,实现布局的自适应能力。
82. 支持自定义网格布局行数和列数,以及每行每列尺寸占比。
93. 支持设置网格布局中子组件的行列间距。
104. 支持设置子组件横跨几行或者几列。
11
12
13
14## 容器组件Grid设置
15
16### 行列数量占比
17通过Grid的组件的columnsTemplate和rowTemplate属性设置网格布局行列数量与尺寸占比。
18
19下面以columnsTemplate为例,介绍该属性的设置,该属性值是一个由多个空格和'数字+fr'间隔拼接的字符串,fr的个数即网格布局的列数,fr前面的数值大小,用于计算该列在网格布局宽度上的占比,最终决定该列的宽度。
20
21```ts
22struct GridExample {
23  @State Number: Array<string> = ['1', '2', '3', '4']
24
25  build() {
26    Column({ space: 5 }) {
27      Grid() {
28        ForEach(this.Number, (num: string) => {
29          GridItem() {
30            Text(`列${num}`)
31              .fontSize(16)
32              .textAlign(TextAlign.Center)
33              .backgroundColor(0xd0d0d0)
34              .width('100%')
35              .height('100%')
36              .borderRadius(5)
37          }
38        })
39      }
40      .columnsTemplate('1fr 1fr 1fr 1fr')
41      .rowsTemplate('1fr')
42      .columnsGap(10)
43      .rowsGap(20)
44      .width('90%')
45      .backgroundColor(0xF0F0F0)
46      .height(100)
47    }.width('100%')
48  }
49}
50```
51
52定义了四个等分的列,每列宽度相等。
53
54```ts
55struct GridExample {
56  @State Number: Array<string> = ['1', '2', '3', '4']
57
58  build() {
59    Column({ space: 5 }) {
60      Grid() {
61        ForEach(this.Number, (num: string) => {
62          GridItem() {
63            Text(`列${num}`)
64              .fontSize(16)
65              .textAlign(TextAlign.Center)
66              .backgroundColor(0xd0d0d0)
67              .width('100%')
68              .height('100%')
69              .borderRadius(5)
70          }
71        })
72      }
73      .columnsTemplate('1fr 2fr 3fr 4fr')
74      .rowsTemplate('1fr')
75      .columnsGap(10)
76      .rowsGap(20)
77      .width('90%')
78      .backgroundColor(0xF0F0F0)
79      .height(100)
80    }.width('100%')
81  }
82}
83```
84
85定义了四列,每列宽度比值为1:2:3:4。
86
87```ts
88struct GridExample {
89  @State Number: Array<string> = ['1', '2', '3']
90
91  build() {
92    Column({ space: 5 }) {
93      Grid() {
94        ForEach(this.Number, (num: string) => {
95          GridItem() {
96            Text(`列${num}`)
97              .fontSize(16)
98              .textAlign(TextAlign.Center)
99              .backgroundColor(0xd0d0d0)
100              .width('100%')
101              .height('100%')
102              .borderRadius(5)
103          }
104        })
105      }
106      .columnsTemplate('4fr 2fr 3fr')
107      .rowsTemplate('1fr')
108      .columnsGap(10)
109      .rowsGap(20)
110      .width('90%')
111      .backgroundColor(0xF0F0F0)
112      .height(100)
113    }.width('100%')
114  }
115}
116```
117
118定义了三列,每列宽度比值为4:2:3。
119
120效果如下:
121
122![](figures/columnTemplate.png)
123
124### 排列方式
125
126通过layoutDirection可以设置网格布局的主轴方向,决定子组件的排列方式。
127可选值包括Row,RowReverse, Column, ColumnReverse四种情况。
128效果如下:
129
130![](figures/gridlayout.png)
131
132### 行列间距
133
134columnsGap用于设置网格子组件GridItem垂直方向的间距,rowsGap用于设置GridItem水平方向的间距。
135
136```ts
137Grid()
138.columnsTemplate('1fr 1fr 1fr 1fr')
139.columnsGap(10)
140.rowsGap(20)
141```
142
143![](figures/columnGap.png)
144
145上图中,设置网格布局子组件间的垂直间距为20,水平间距为10。
146
147## 网格子组件GridItem设置
148
149### 设置子组件占的行列数
150
151网格布局的行列标号从1开始,依次编号。
152
153子组件横跨多行时,通过rowStart设置子组件起始行编号,rowEnd设置终点行编号。当rowStart值与rowEnd值相同时,子组件只占一个网格。示例如下:
154
155```ts
156Grid() {
157    GridItem() {
158      Text('5')
159        .fontSize(16)
160        .textAlign(TextAlign.Center)
161        .textStyle()
162    }.rowStart(2).rowEnd(3)  // 5子组件从第二行到第三行
163
164    GridItem() {
165      Text('4')
166        .fontSize(16)
167        .textAlign(TextAlign.Center)
168        .textStyle()
169    }.columnStart(4).columnEnd(5) // 4从第四列到第五列
170
171    GridItem() {
172      Text('6')
173        .fontSize(16)
174        .textAlign(TextAlign.Center)
175        .textStyle()
176    }.columnStart(2).columnEnd(4)  // 6从第二列到第四列
177
178    GridItem() {
179      Text('9')
180        .fontSize(16)
181        .textAlign(TextAlign.Center)
182        .textStyle()
183    }.columnStart(3).columnEnd(4)    // 从第三列到第四列
184}
185.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
186.rowsTemplate('1fr 1fr 1fr')
187.columnsGap(10)
188.rowsGap(20)
189.width('90%')
190.backgroundColor(0xF0F0F0)
191.height('200vp')
192.layoutDirection(GridDirection.Column)
193```
194
195![](figures/griditem.png)
196
197## 场景示例
198
199使用grid布局实现一个计算器的排布效果,代码如下:
200
201```ts
202@Entry
203@Component
204struct GridExample {
205  @State Number: Array<string> = ['1', '2', '3', '+', '4', '5', '6', '-', '7', '8', '9', '*', '0', '.', '/']
206
207  @Styles textStyle(){
208    .backgroundColor(0xd0d0d0)
209    .width('100%')
210    .height('100%')
211    .borderRadius(5)
212  }
213
214  build() {
215    Column({ space: 5 }) {
216      Grid() {
217        GridItem() {
218          Text('0')
219            .fontSize(30)
220            .textStyle()
221        }.columnStart(1).columnEnd(4)
222
223        GridItem() {
224          Text('清空')
225            .fontSize(16)
226            .textAlign(TextAlign.Center)
227            .textStyle()
228        }.columnStart(1).columnEnd(2)
229
230        GridItem() {
231          Text('回退')
232            .fontSize(16)
233            .textAlign(TextAlign.Center)
234            .textStyle()
235        }.columnStart(3).columnEnd(4)
236
237        ForEach(this.Number, (day: string) => {
238          if (day === '0') {
239            GridItem() {
240              Text(day)
241                .fontSize(16)
242                .textAlign(TextAlign.Center)
243                .textStyle()
244            }.columnStart(1).columnEnd(2)
245          } else {
246            GridItem() {
247              Text(day)
248                .fontSize(16)
249                .textAlign(TextAlign.Center)
250                .textStyle()
251            }
252          }
253        })
254      }
255      .columnsTemplate('1fr 1fr 1fr 1fr')
256      .rowsTemplate('2fr 1fr 1fr 1fr 1fr 1fr')
257      .columnsGap(10)
258      .rowsGap(15)
259      .width('90%')
260      .backgroundColor(0xF0F0F0)
261      .height('70%')
262    }.width('100%').margin({ top: 5 })
263  }
264}
265```
266
267在大屏设备上展示效果如下:
268
269![](figures/gridExp1.png)
270
271在小屏设备下展示效果如下:
272
273![](figures/gridExp2.png)
274