• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Creating a Grid
2
3
4## Overview
5
6The grid layout consists of cells formed by rows and columns. You can specify the cells where items are located to form various layouts. The grid layout excels at dividing a page into regions and defining the proportion of child components. It is a key adaptive layout and applies to scenarios such as photo gallery, calendar, and calculator.
7
8ArkUI provides the \<[Grid](../reference/arkui-ts/ts-container-grid.md)> container component and \<[GridItem](../reference/arkui-ts/ts-container-griditem.md)> child component for building grid layouts. The former is used to set parameters related to the grid layout, while the latter is used to define features related to child components. The **\<Grid>** component allows creation of child components with conditional rendering, rendering of repeated content, and [lazy data loading](../quick-start/arkts-rendering-control-lazyforeach.md).
9
10
11## Layout and Constraints
12
13Each item in the **\<Grid>** container corresponds to a **\<GridItem>** component, as shown below.
14
15  **Figure 1** Relationship between \<Grid> and \<GridItem> components
16![en-us_image_0000001511900472](figures/en-us_image_0000001511900472.png)
17
18>**NOTE**
19>
20>The **\<Grid>** component accepts only **\<GridItem>** as its child components.
21
22The grid layout is a two-dimensional layout. The **\<Grid>** component allows you to define the number of rows and columns, proportion of each row and column, number of rows or columns that child components span, and the horizontal and vertical alignment. When the **\<Grid>** container size changes, the child components and spacing are adjusted proportionally. By leveraging these layout capabilities, you can build grid layouts of different styles, as shown below.
23
24  **Figure 2** Grid layout
25![en-us_image_0000001562700473](figures/en-us_image_0000001562700473.png)
26
27The size of the **\<Grid>** component follows its width and height settings (if configured) or adapts to the size of its parent component.
28
29Depending on the number of rows and columns and the proportion, the **\<Grid>** component behaves as follows:
30
31- If both the number and proportion are set for rows or columns, the **\<Grid>** component displays only elements in the fixed number of rows or columns. Other elements are not displayed, and the component cannot be scrolled.
32
33- If only the number or proportion is set for rows or columns, elements are arranged in the specified direction, and excess elements can be displayed in scrolling mode.
34
35- If neither the number nor the proportion is set for rows or columns, elements are arranged in the layout direction. The number of rows and columns is determined by the layout direction and the width and height of a single grid. Elements that exceed the range of rows and columns are not displayed, and the **\<Grid>** component cannot be scrolled.
36
37>**NOTE**
38>
39>Whenever possible, set the number or proportion for rows or columns for layout.
40
41
42## Setting the Arrangement Mode
43
44
45### Setting the Number and Proportion of Rows and Columns
46
47You can set the number and proportion of rows and columns to determine the overall arrangement mode of the grid layout. To do so, use the **rowsTemplate** and **columnsTemplate** attributes of the **\<Grid>** component.
48
49The values of **rowsTemplate** and **columnsTemplate** are a string consisting of 'number+fr' segments, separated by spaces. Wherein **frs** indicates the number of rows or columns in the grid layout, and the number before **fr** is used to calculate the proportion of the row or column in the grid width, thereby determining the width of the row or column.
50
51  **Figure 3** Example of the proportion of rows and columns
52![en-us_image_0000001562820833](figures/en-us_image_0000001562820833.png)
53
54The preceding figure shows a grid layout with three rows and three columns. The grid layout is divided into three parts in the vertical direction with each row taking up 1/3, and four parts in the horizontal direction with the first column taking up 1/4, the second column 2/4, and the third column 1/4.
55
56This layout can be implemented by setting **rowsTemplate** to **'1fr 1fr 1fr'** and **columnsTemplate** to **'1fr 2fr 1fr'**.
57
58
59```ts
60Grid() {
61  ...
62}
63.rowsTemplate('1fr 1fr 1fr')
64.columnsTemplate('1fr 2fr 1fr')
65```
66
67>**NOTE**
68>
69>When **rowsTemplate** or **columnsTemplate** is set for the **\<Grid>** component, its **layoutDirection**, **maxCount**, **minCount**, and **cellLength** attributes do not take effect. For details about the attributes, see [Grid Attributes](../reference/arkui-ts/ts-container-grid.md#attributes).
70
71
72### Setting the Number of Rows and Columns Occupied by a Child Component
73
74In real-world applications, an uneven grid layout, where grid cells span a varying number of cells and rows, is as common as its even counterpart. To implement an uneven grid layout, as shown below, you can set **rowStart**, **rowEnd**, **columnStart**, and **columnEnd** of **\<GridItem>**.
75
76  **Figure 4** Uneven grid layout
77
78![en-us_image_0000001511900480](figures/en-us_image_0000001511900480.png)
79
80A common application with an uneven grid layout is the calculator. As shown in the following figure, the **0** key spans the first and second columns, and the **=** key spans the fifth and sixth rows. For a grid layout created using the **\<Grid>** component, the row and column numbers start from 1 and increase continuously.
81
82  **Figure 5** Calculator
83
84![en-us_image_0000001511421292](figures/en-us_image_0000001511421292.png)
85
86For a single grid cell, the **rowStart** and** rowEnd** attributes indicate the start and end row numbers of the current element, and the **columnStart** and **columnEnd** attributes indicate the start and end column numbers of the current element.
87
88Therefore, for the **0** key to span the first and second columns, just set **columnStart** and **columnEnd** of the corresponding **\<GridItem>** component to **1** and **2**.
89
90
91```ts
92GridItem() {
93  Text(key)
94    ...
95}
96.columnStart(1)
97.columnEnd(2)
98```
99
100For the **=** key to span the fifth and sixth rows, set **rowStart** and **rowEnd** of the corresponding **\<GridItem>** component to **5** and **6**
101
102
103```ts
104GridItem() {
105  Text(key)
106    ...
107}
108.rowStart(5)
109.rowEnd(6)
110```
111
112
113### Setting the Main Axis Direction
114
115When neither the number nor proportion is set for rows and columns in a grid layout, you can use the **layoutDirection** attribute to set the main axis direction and thereby specify the arrangement mode of child components. In addition, you can use the **minCount** and **maxCount** attributes to restrict the number of grid cells along the main axis.
116
117  **Figure 6** Main axis direction
118
119![en-us_image_0000001562700469](figures/en-us_image_0000001562700469.png)
120
121When **layoutDirection** is set to **Row**, child components are arranged from left to right. When a row is full, a new row will be added. When **layoutDirection** is set to **Column**, child components are arranged from top to bottom. When a column is full, a new column will be added. In this example, the **maxCount** attribute is set to **3**, indicating that the maximum number of grid cells displayed along the main axis is 3.
122
123
124```ts
125Grid() {
126  ...
127}
128.maxCount(3)
129.layoutDirection(GridDirection.Row)
130```
131
132>**NOTE**
133>
134>- The **layoutDirection** attribute takes effect only when **rowsTemplate** and **columnsTemplate** are not set. In this case, child components are arranged in the direction set by **layoutDirection**.
135>- When only **rowsTemplate** is set, the main axis of the grid runs in the horizontal direction, and the cross axis runs in the vertical direction.
136>- When only **columnsTemplate** is set, the main axis of the grid runs in the vertical direction, and the cross axis runs in the horizontal direction.
137
138
139## Displaying Data in a Grid Layout
140
141The grid layout organizes its internal elements in two-dimensional layout mode, as shown in the following figure.
142
143**Figure 7** General office services
144
145![en-us_image_0000001563060729](figures/en-us_image_0000001563060729.png)
146
147The **\<Grid>** component can display a group of **\<GridItem>** child components in two-dimensional layout mode.
148
149
150```ts
151Grid() {
152  GridItem() {
153    Text('Conference')
154      ...
155  }
156
157  GridItem() {
158    Text('Sign-in')
159      ...
160  }
161
162  GridItem() {
163    Text ('Vote')
164      ...
165  }
166
167  GridItem() {
168    Text ('Print')
169      ...
170  }
171}
172.rowsTemplate('1fr 1fr')
173.rowsTemplate('1fr 1fr')
174```
175
176For multiple **\<GridItem>** components with similar content structures, you are advised to nest them in **ForEach** statements to reduce repeated code.
177
178
179```ts
180@Component
181struct OfficeService {
182  @State services: Array<string> = ['Conference', 'Vote','Sign-in', 'Print']
183  ...
184
185  build() {
186    Column() {
187      Grid() {
188        ForEach(this.services, service => {
189          GridItem() {
190            Text(service)
191              ...
192          }
193        }, service => service)
194      }
195      .rowsTemplate('1fr 1fr')
196      .rowsTemplate('1fr 1fr')
197      ...
198    }
199    ...
200  }
201}
202```
203
204
205## Setting the Gap Between Rows and Columns
206
207The horizontal spacing between two grid cells is called row spacing, and the vertical spacing is called column spacing, as shown in the following figure.
208
209**Figure 8** Row spacing and column spacing
210
211![en-us_image_0000001511580908](figures/en-us_image_0000001511580908.png)
212
213You can use **rowsGap** and **columnsGap** to set the row spacing and column spacing of the grid layout. In the calculator shown in Figure 5, the row spacing is 15 vp, and the column spacing is 10vp.
214
215
216```ts
217Grid() {
218  ...
219}
220.columnsGap(10)
221.rowsGap(15)
222```
223
224
225## Building a Scrollable Grid Layout
226
227The scrollable grid layout is often used on the file list, product list, video list, and similar pages, as shown in the following figure. When only the number or proportion is set for rows and columns, that is, only the **rowsTemplate** or **columnsTemplate** attribute is set, the elements in the grid are arranged in the configured direction. When the content goes beyond the display area, the grid can be scrolled.
228
229**Figure 9** Horizontal scrollable grid layout
230
231![en-us_image_0000001511740512](figures/en-us_image_0000001511740512.gif)
232
233If **columnsTemplate** is set, the grid scrolls vertically. If **rowsTemplate** is set, the grid scrolls horizontally.
234
235In the horizontal scrollable grid layout shown in the preceding figure, **rowsTemplate** is set but **columnsTemplate** is not. When the content exceeds the width of the grid, the grid can scroll horizontally to display the content outside of the display area.
236
237
238```ts
239@Component
240struct Shopping {
241  @State services: Array<string> = ['Live', 'Premium', ...]
242  ...
243
244  build() {
245    Column({ space: 5 }) {
246      Grid() {
247        ForEach(this.services, (service: string, index) => {
248          GridItem() {
249            ...
250          }
251          .width('25%')
252        }, service => service)
253      }
254      .rowsTemplate('1fr 1fr') // Set only the rowsTemplate attribute. When the content exceeds the display area of the grid, the grid can be scrolled horizontally.
255      .rowsGap(15)
256      ...
257    }
258    ...
259  }
260}
261```
262
263
264## Controlling the Scrolling Position
265
266Similar to the Back to top button in a list layout, the feature of controlling the scrolling position is commonly used in the grid layout, for example, page turning in the calendar application, as shown below.
267
268  **Figure 10** Page turning in the calendar application
269
270![en-us_image_0000001562940549](figures/en-us_image_0000001562940549.gif)
271
272When the **\<Grid>** component is initialized, it can be bound to a [Scroller](../reference/arkui-ts/ts-container-scroll.md/#scroller) object for scrolling control. In this example, the [scrollPage](../reference/arkui-ts/ts-container-scroll.md/#scrollpage) API of the **Scroller** object is used to turn pages.
273
274
275```ts
276private scroller: Scroller = new Scroller()
277```
278
279On the calendar page, when a user clicks the **Next** button, the application responds to the click event by setting the **next** parameter in the **scrollPage** API to **true** to scroll to the next page.
280
281
282```ts
283Column({ space: 5 }) {
284  Grid(this.scroller) {
285    ...
286  }
287  .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')
288  ...
289
290 Row({space: 20}) {
291   Button ('Previous')
292     .onClick(() => {
293       this.scroller.scrollPage({
294         next: false
295       })
296     })
297
298   Button ('Next')
299     .onClick(() => {
300       this.scroller.scrollPage({
301         next: true
302       })
303     })
304 }
305}
306...
307```
308
309
310## Performance Optimization
311
312Just as [LazyForEach](../quick-start/arkts-rendering-control-lazyforeach.md) is recommended for [handling a long list](arkts-layout-development-create-list.md#handling-a-long-list), it is also recommended for a scrolling grid layout when a large number of grid items is involved.
313
314For details about the implementation, see the example in [LazyForEach: Lazy Data Loading](../quick-start/arkts-rendering-control-lazyforeach.md).
315
316When the grid is rendered in lazy loading mode, to improve the grid scrolling experience and minimize white blocks during grid scrolling, you can use the **cachedCount** parameter of the **\<Grid>** component. This parameter sets the number of grid items preloaded outside of the screen and is valid only in **LazyForEach**.
317
318  Specifically, the number of the grid items to cache before and after the currently displayed one equals the value of **cachedCount** multiplied by the number of columns. Grid items that exceed the display and cache range are released.
319
320```ts
321Grid() {
322  LazyForEach(this.dataSource, item => {
323    GridItem() {
324      ...
325    }
326  })
327}
328.cachedCount(3)
329```
330
331>**NOTE**
332>
333>A greater **cachedCount** value may result in higher CPU and memory overhead of the UI. Adjust the value by taking into account both the comprehensive performance and user experience.
334
335##
336
337
338
339-
340