1# Grid
2
3The **Grid** component consists of cells formed by rows and columns. You can specify the cells where items are located to form various layouts.
4
5>  **NOTE**
6>
7>  This component is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version.
8
9
10## Child Components
11
12Only the [GridItem](ts-container-griditem.md) child component is allowed, with support for [if/else](../../../quick-start/arkts-rendering-control-ifelse.md), [ForEach](../../../quick-start/arkts-rendering-control-foreach.md), [LazyForEach](../../../quick-start/arkts-rendering-control-lazyforeach.md), and [Repeat](../../../quick-start/arkts-new-rendering-control-repeat.md) rendering control.
13
14>  **NOTE**
15>
16>  Below are the rules for calculating the indexes of the child components of **Grid**:
17>
18>  The index increases in ascending order of child components.
19>
20>  In the **if/else** statement, only the child components in the branch where the condition is met participate in the index calculation.
21>
22>  In the **ForEach**, **LazyForEach**, or **Repeat** statement, the indexes of all expanded child nodes are calculated.
23>
24>  After changes occur in [if/else](../../../quick-start/arkts-rendering-control-ifelse.md), [ForEach](../../../quick-start/arkts-rendering-control-foreach.md), [LazyForEach](../../../quick-start/arkts-rendering-control-lazyforeach.md), or [Repeat](../../../quick-start/arkts-new-rendering-control-repeat.md), the indexes of the child nodes are updated.
25>
26>  The child component that has the **visibility** attribute set to **Hidden** or **None** is included in the index calculation.
27>
28>  The child component that has the **visibility** attribute set to **None** is not displayed, but still takes up the corresponding cell.
29>
30>  The child component that has the **position** attribute set is displayed in the corresponding cell, offset by the distance specified by **position** relative to the upper left corner of the grid. This child component does not scroll with the corresponding cell and is not displayed after the corresponding cell extends beyond the display range of the grid.
31>
32>  When there is a gap between child components, it is filled as much as possible based on the current display area. Therefore, the relative position of grid items may change as the grid scrolls.
33
34## APIs
35
36Grid(scroller?: Scroller, layoutOptions?: GridLayoutOptions)
37
38**Atomic service API**: This API can be used in atomic services since API version 11.
39
40**System capability**: SystemCapability.ArkUI.ArkUI.Full
41
42**Parameters**
43
44| Name  | Type                                   | Mandatory| Description                                                    |
45| -------- | ------------------------------------------- | ---- | ------------------------------------------------------------ |
46| scroller | [Scroller](ts-container-scroll.md#scroller) | No  | Controller, which can be bound to scrollable components.<br>**NOTE**<br>The scroller cannot be bound to other scrollable components, such as [List](ts-container-list.md), [Grid](ts-container-grid.md), or [Scroll](ts-container-scroll.md).|
47| layoutOptions<sup>10+</sup> | [GridLayoutOptions](#gridlayoutoptions10) | No| Grid layout options.|
48
49## GridLayoutOptions<sup>10+</sup>
50
51**Atomic service API**: This API can be used in atomic services since API version 11.
52
53**System capability**: SystemCapability.ArkUI.ArkUI.Full
54
55Defines the layout options. In this API, **irregularIndexes** and **onGetIrregularSizeByIndex** can be used for grids where either **rowsTemplate** or **columnsTemplate** is set. You can specify an index array and set the number of rows and columns to be occupied by a grid item with the specified index. For details, see Example 3. **onGetRectByIndex** can be used for grids where both **rowsTemplate** and **columnsTemplate** are set. It specifies the position and size for the grid item with the specified index. For details, see Example 1.
56
57| Name   | Type     | Mandatory  | Description                   |
58| ----- | ------- | ---- | --------------------- |
59| regularSize  | [number, number]  | Yes   | Number of rows and columns occupied by a grid item with regular size. The only supported value is **[1, 1]**, meaning that the grid item occupies one row and one column.<br>**Atomic service API**: This API can be used in atomic services since API version 11. |
60| irregularIndexes | number[] | No   | Indexes of the grid item with an irregular size in the grid. When **onGetIrregularSizeByIndex** is not set, the grid item specified in this parameter occupies an entire row of the grid that scrolls vertically or an entire column of the grid that scrolls horizontally.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
61| onGetIrregularSizeByIndex | (index: number) => [number, number] | No   | Number of rows and columns occupied by the grid item with an irregular size. This parameter is used together with **irregularIndexes**. In versions earlier than API version 12, the vertical scrolling grid does not support grid items spanning multiple rows, and the horizontal scrolling grid does not support grid items spanning multiple columns.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
62| onGetRectByIndex<sup>11+</sup> | (index: number) => [number, number,number,number] | No | Position and size of the grid item with the specified index, in the format of [rowStart,columnStart,rowSpan,columnSpan],<br>where **rowStart** indicates the row start position, **columnStart** indicates the column start position,<br>**rowSpan** indicates the number of rows occupied by the grid item, and **columnSpan** indicates the number of columns occupied by the grid item. Their values are unitless.<br>The values of **rowStart** and **columnStart** are natural numbers greater than or equal to 0. If a negative value is set, the default value **0** is used.<br>The values of **rowSpan** and **columnSpan** are natural numbers greater than or equal to 1. If a decimal is set, it is rounded down. If the decimal set is less than 1, the value **1** is used.<br>**NOTE**<br>Case 1: If a grid item finds that the start position specified for it is already occupied, it searches for an available start position from left to right and from top to bottom, starting from position [0,0].<br>Case 2: If any space other than the start position specified for a grid item is occupied, the grid item is displayed within the available space left.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
63
64## Attributes
65
66In addition to [universal attributes](ts-universal-attributes-size.md) and [scrollable component common attributes](ts-container-scrollable-common.md#attributes), the following attributes are also supported.
67
68### columnsTemplate
69
70columnsTemplate(value: string)
71
72Sets the number of columns, fixed column width, or minimum column width of the grid. If this attribute is not set, one column will be used.
73
74For example, **'1fr 1fr 2fr'** indicates three columns, with the first column taking up 1/4 of the parent component's full width, the second column 1/4, and the third column 2/4.
75
76**columnsTemplate('repeat(auto-fit, track-size)')**: The layout automatically calculates the number of columns and the actual column width, while adhering to the minimum column width specified with **track-size**.
77
78**columnsTemplate('repeat(auto-fill, track-size)')**: The layout automatically calculates the number of columns based on the fixed column width specified with **track-size**.
79
80**columnsTemplate('repeat(auto-stretch, track-size)')**: The layout uses **columnsGap** to define the minimum gap between columns and automatically calculates the number of columns and the actual gap size based on the fixed column width specified with **track-size**.
81
82**repeat**, **auto-fit**, **auto-fill**, and **auto-stretch** are keywords. **track-size** indicates the column width, in the unit of px, vp (default), %, or any valid digit. The value must be greater than or equal to one valid column width.<br>
83In **auto-stretch** mode, **track-size** must be a valid column width value, in the unit of px, vp, or any valid digit; percentage values (%) are not supported.
84
85For visual reference, see [Example 8](#example-8).
86
87If this attribute is set to **'0fr'**, the column width is 0, and grid item in the column is not displayed. If this attribute is set to any other invalid value, the grid item is displayed as one column.
88
89**Atomic service API**: This API can be used in atomic services since API version 11.
90
91**System capability**: SystemCapability.ArkUI.ArkUI.Full
92
93**Parameters**
94
95| Name| Type  | Mandatory| Description                              |
96| ------ | ------ | ---- | ---------------------------------- |
97| value  | string | Yes  | Number of columns or minimum column width of the grid.|
98
99### rowsTemplate
100
101rowsTemplate(value: string)
102
103Sets the number of rows, fixed row height, or minimum row height of the grid. If this attribute is not set, one row will be used.
104
105For example, **'1fr 1fr 2fr'** indicates three rows, with the first row taking up 1/4 of the parent component's full height, the second row 1/4, and the third row 2/4.
106
107**rowsTemplate('repeat(auto-fit, track-size)')**: The layout automatically calculates the number of rows and the actual row height, while adhering to the minimum row height specified with **track-size**.
108
109**rowsTemplate('repeat(auto-fill, track-size)')**: The layout automatically calculates the number of rows based on the fixed row height specified with **track-size**.
110
111**rowsTemplate('repeat(auto-stretch, track-size)')**: The layout uses **rowsGap** to define the minimum gap between rows and automatically calculates the number of rows and the actual gap size based on the fixed row height specified with **track-size**.
112
113**repeat**, **auto-fit**, **auto-fill**, and **auto-stretch** are keywords. **track-size** indicates the row height, in the unit of px, vp (default), %, or any valid digit. The value must be greater than or equal to one valid row height.<br>
114In **auto-stretch** mode, **track-size** must be a valid row height value, in the unit of px, vp, or any valid digit; percentage values (%) are not supported.
115
116If this attribute is set to **'0fr'**, the row width is 0, and grid item in the row is not displayed. If this attribute is set to any other invalid value, the grid item is displayed as one row.
117
118**Atomic service API**: This API can be used in atomic services since API version 11.
119
120**System capability**: SystemCapability.ArkUI.ArkUI.Full
121
122**Parameters**
123
124| Name| Type  | Mandatory| Description                              |
125| ------ | ------ | ---- | ---------------------------------- |
126| value  | string | Yes  | Number of rows or minimum row height of the grid.|
127
128>  **NOTE**
129>
130>  Depending on the settings of the **rowsTemplate** and **columnsTemplate** attributes, the **Grid** component supports the following layout modes:
131>
132>  1. **rowsTemplate** and **columnsTemplate** are both set
133>
134>  - The **Grid** component displays only elements in a fixed number of rows and columns and cannot be scrolled.
135>  - In this mode, the following attributes do not take effect: **layoutDirection**, **maxCount**, **minCount**, and **cellLength**.
136>  - If the width and height of a grid are not set, the grid adapts to the size of its parent component by default.
137>  - The size of the grid rows and columns is the size of the grid content area minus the gap between rows and columns. It is allocated based on the proportion of each row and column.
138>  - By default, the grid items fill the entire grid.
139>
140>  2. Either **rowsTemplate** or **columnsTemplate** is set
141>
142>  - The **Grid** component arranges elements in the specified direction and allows for scrolling to display excess elements.
143>  - If **columnsTemplate** is set, the component scrolls vertically, the main axis runs vertically, and the cross axis runs horizontally.
144>  - If **rowsTemplate** is set, the component scrolls horizontally, the main axis runs horizontally, and the cross axis runs vertically.
145>  - In this mode, the following attributes do not take effect: **layoutDirection**, **maxCount**, **minCount**, and **cellLength**.
146>  - The cross axis size of the grid is the cross axis size of the grid content area minus the gaps along the cross axis. It is allocated based on the proportion of each row and column.
147>  - The main axis size of the grid is the maximum value of the main axis sizes of all grid items in the cross axis direction of the grid.
148>
149>  3. Neither **rowsTemplate** nor **columnsTemplate** is set
150>
151>  - The **Grid** component arranges elements in the direction specified by **layoutDirection**. The number of columns is jointly determined by the grid width, width of the first element, **minCount**, **maxCount**, and **columnsGap**.
152>  - The number of rows is jointly determined by the grid height, height of the first element, **cellLength**, and **rowsGap**. Elements outside the determined range of rows and columns are not displayed and cannot be viewed through scrolling.
153>  - In this mode, only the following attributes take effect: **layoutDirection**, **maxCount**, **minCount**, **cellLength**, **editMode**, **columnsGap**, and **rowsGap**.
154>  - When **layoutDirection** is set to **Row**, child components are arranged from left to right. When a row is full, a new row will be added. If the remaining height is insufficient, no more elements will be laid out, and the whole content is centered at the top.
155>  - When **layoutDirection** is set to **Column**, elements are arranged column by column from top to bottom. If the remaining height is insufficient, no more elements will be laid out, and the whole content is centered at the top.
156>  - If there are no grid items in the grid, the width and height of the grid are set to 0.
157>
158
159### columnsGap
160
161columnsGap(value: Length)
162
163Sets the gap between columns. A value less than 0 evaluates to the default value.
164
165**Atomic service API**: This API can be used in atomic services since API version 11.
166
167**System capability**: SystemCapability.ArkUI.ArkUI.Full
168
169**Parameters**
170
171| Name| Type                        | Mandatory| Description                        |
172| ------ | ---------------------------- | ---- | ---------------------------- |
173| value  | [Length](ts-types.md#length) | Yes  | Gap between columns.<br>Default value: **0**|
174
175### rowsGap
176
177rowsGap(value: Length)
178
179Sets the gap between rows. A value less than 0 evaluates to the default value.
180
181**Atomic service API**: This API can be used in atomic services since API version 11.
182
183**System capability**: SystemCapability.ArkUI.ArkUI.Full
184
185**Parameters**
186
187| Name| Type                        | Mandatory| Description                        |
188| ------ | ---------------------------- | ---- | ---------------------------- |
189| value  | [Length](ts-types.md#length) | Yes  | Gap between rows.<br>Default value: **0**|
190
191### scrollBar
192
193scrollBar(value: BarState)
194
195Sets the scrollbar state.
196
197**Atomic service API**: This API can be used in atomic services since API version 11.
198
199**System capability**: SystemCapability.ArkUI.ArkUI.Full
200
201**Parameters**
202
203| Name| Type                                     | Mandatory| Description                                                        |
204| ------ | ----------------------------------------- | ---- | ------------------------------------------------------------ |
205| value  | [BarState](ts-appendix-enums.md#barstate) | Yes  | Scrollbar state.<br>Default value: **BarState.Auto**<br>**NOTE**<br>In API version 9 and earlier versions, the default value is **BarState.Off**. Since API version 10, the default value is **BarState.Auto**.|
206
207### scrollBarColor
208
209scrollBarColor(value: Color | number | string)
210
211Sets the scrollbar color.
212
213**Atomic service API**: This API can be used in atomic services since API version 11.
214
215**System capability**: SystemCapability.ArkUI.ArkUI.Full
216
217**Parameters**
218
219| Name| Type                                                        | Mandatory| Description          |
220| ------ | ------------------------------------------------------------ | ---- | -------------- |
221| value  | [Color](ts-appendix-enums.md#color) \| number \| string | Yes  | Scrollbar color.<br>Default value: **'\#182431'** (40% opacity)|
222
223### scrollBarWidth
224
225scrollBarWidth(value: number | string)
226
227Sets the scrollbar width. This attribute cannot be set in percentage. After the width is set, the scrollbar is displayed with the set width in normal state and pressed state. If the set width exceeds the height of the **Grid** component on the main axis, the scrollbar reverts to the default width.
228
229**Atomic service API**: This API can be used in atomic services since API version 11.
230
231**System capability**: SystemCapability.ArkUI.ArkUI.Full
232
233**Parameters**
234
235| Name| Type                      | Mandatory| Description                                     |
236| ------ | -------------------------- | ---- | ----------------------------------------- |
237| value  | number \| string | Yes  | Scrollbar width.<br>Default value: **4**<br>Unit: vp|
238
239### cachedCount
240
241cachedCount(value: number)
242
243Sets the number of grid items to be cached (preloaded). It works only in [LazyForEach](../../../quick-start/arkts-rendering-control-lazyforeach.md) and [Repeat](../../../quick-start/arkts-new-rendering-control-repeat.md) with the **virtualScroll** option enabled. A value less than 0 evaluates to the default value. <!--Del-->For details, see [Minimizing White Blocks During Swiping](../../../performance/arkts-performance-improvement-recommendation.md#minimizing-white-blocks-during-swiping).<!--DelEnd-->
244
245The number of the grid items to be cached before and after the currently displayed one equals the value of **cachedCount** multiplied by the number of columns.
246
247In [LazyForEach](../../../quick-start/arkts-rendering-control-lazyforeach.md) and [Repeat](../../../quick-start/arkts-new-rendering-control-repeat.md) with the **virtualScroll** option enabled, grid items that are outside the display and cache range will be released.
248
249**Atomic service API**: This API can be used in atomic services since API version 11.
250
251**System capability**: SystemCapability.ArkUI.ArkUI.Full
252
253**Parameters**
254
255| Name| Type  | Mandatory| Description                                  |
256| ------ | ------ | ---- | -------------------------------------- |
257| value  | number | Yes  | Number of grid items to be cached (preloaded).<br>Default value: **1**|
258
259### cachedCount<sup>14+</sup>
260
261cachedCount(count: number, show: boolean)
262
263Sets the number of grid items to be cached (preloaded) and specifies whether to display the preloaded nodes.
264
265The number of the grid items to be preloaded before and after the currently displayed one equals the value of **cachedCount** multiplied by the number of columns. This attribute can be combined with the [clip](ts-universal-attributes-sharp-clipping.md#clip12) or [content clipping](ts-container-scrollable-common.md#clipcontent14) attributes to display the preloaded nodes.
266
267**Atomic service API**: This API can be used in atomic services since API version 14.
268
269**System capability**: SystemCapability.ArkUI.ArkUI.Full
270
271**Parameters**
272
273| Name| Type  | Mandatory| Description                                  |
274| ------ | ------ | ---- | -------------------------------------- |
275| count  | number | Yes  | Number of grid items to be preloaded.<br>Default value: **1**|
276| show  | boolean | Yes  | Whether to display the preloaded nodes.<br> Default value: **false**|
277
278### editMode<sup>8+</sup>
279
280editMode(value: boolean)
281
282Sets whether to enable edit mode. In edit mode, the user can drag the [grid items](ts-container-griditem.md) in the **Grid** component.
283
284**Atomic service API**: This API can be used in atomic services since API version 11.
285
286**System capability**: SystemCapability.ArkUI.ArkUI.Full
287
288**Parameters**
289
290| Name| Type  | Mandatory| Description                                    |
291| ------ | ------ | ---- | ---------------------------------------- |
292| value  | boolean | Yes  | Whether to enable edit mode.<br>Default value: **false**|
293
294### layoutDirection<sup>8+</sup>
295
296layoutDirection(value: GridDirection)
297
298Sets the main axis direction of the grid.
299
300**Atomic service API**: This API can be used in atomic services since API version 11.
301
302**System capability**: SystemCapability.ArkUI.ArkUI.Full
303
304**Parameters**
305
306| Name| Type                                    | Mandatory| Description                                          |
307| ------ | ---------------------------------------- | ---- | ---------------------------------------------- |
308| value  | [GridDirection](#griddirection8) | Yes  | Main axis direction of the grid.<br>Default value: **GridDirection.Row**|
309
310### maxCount<sup>8+</sup>
311
312maxCount(value: number)
313
314Sets the maximum number of rows or columns that can be displayed. A value less than 1 evaluates to the default value.
315
316When **layoutDirection** is **Row** or **RowReverse**, the value indicates the maximum number of columns that can be displayed.
317
318When **layoutDirection** is **Column** or **ColumnReverse**, the value indicates the maximum number of rows that can be displayed.
319
320If the value of **maxCount** is smaller than that of **minCount**, the default values of **maxCount** and **minCount** are used.
321
322**Atomic service API**: This API can be used in atomic services since API version 11.
323
324**System capability**: SystemCapability.ArkUI.ArkUI.Full
325
326**Parameters**
327
328| Name| Type  | Mandatory| Description                                         |
329| ------ | ------ | ---- | --------------------------------------------- |
330| value  | number | Yes  | Maximum number of rows or columns that can be displayed.<br>Default value: **Infinity**|
331
332### minCount<sup>8+</sup>
333
334minCount(value: number)
335
336Sets the minimum number of rows or columns that can be displayed. A value less than 1 evaluates to the default value.
337
338When **layoutDirection** is **Row** or **RowReverse**, the value indicates the minimum number of columns that can be displayed.
339
340When **layoutDirection** is **Column** or **ColumnReverse**, the value indicates the minimum number of rows that can be displayed.
341
342**Atomic service API**: This API can be used in atomic services since API version 11.
343
344**System capability**: SystemCapability.ArkUI.ArkUI.Full
345
346**Parameters**
347
348| Name| Type  | Mandatory| Description                                  |
349| ------ | ------ | ---- | -------------------------------------- |
350| value  | number | Yes  | Minimum number of rows or columns that can be displayed.<br>Default value: **1**|
351
352### cellLength<sup>8+</sup>
353
354cellLength(value: number)
355
356Sets the height per row or width per column.
357
358When **layoutDirection** is **Row** or **RowReverse**, the value indicates the height per row.
359
360When **layoutDirection** is **Column** or **ColumnReverse**, the value indicates the width per column.
361
362**Atomic service API**: This API can be used in atomic services since API version 11.
363
364**System capability**: SystemCapability.ArkUI.ArkUI.Full
365
366**Parameters**
367
368| Name| Type  | Mandatory| Description                                                   |
369| ------ | ------ | ---- | ------------------------------------------------------- |
370| value  | number | Yes  | Height per row or width per column.<br>Default value: size of the first element<br>Unit: vp|
371
372### multiSelectable<sup>8+</sup>
373
374multiSelectable(value: boolean)
375
376Sets whether to enable multiselect. When multiselect is enabled, you can use the **selected** attribute and **onSelect** event to obtain the selected status of grid items; you can also set the [style](./ts-universal-attributes-polymorphic-style.md) for the selected state (by default, no style is set for the selected state).
377
378**Atomic service API**: This API can be used in atomic services since API version 11.
379
380**System capability**: SystemCapability.ArkUI.ArkUI.Full
381
382**Parameters**
383
384| Name| Type   | Mandatory| Description                                                        |
385| ------ | ------- | ---- | ------------------------------------------------------------ |
386| value  | boolean | Yes  | Whether to enable multiselect.<br>Default value: **false**<br>**false**: Multiselect is disabled. **true**: Multiselect is disabled.|
387
388### supportAnimation<sup>8+</sup>
389
390supportAnimation(value: boolean)
391
392Sets whether to enable animation. Currently, the grid item drag animation is supported. Animation is supported only in scrolling mode (only **rowsTemplate** or **columnsTemplate** is set).<br>Drag animations are only supported in grids with fixed size rules; scenarios involving spanning across rows or columns are not supported.
393
394**Atomic service API**: This API can be used in atomic services since API version 11.
395
396**System capability**: SystemCapability.ArkUI.ArkUI.Full
397
398**Parameters**
399
400| Name| Type   | Mandatory| Description                            |
401| ------ | ------- | ---- | -------------------------------- |
402| value  | boolean | Yes  | Whether to enable animation.<br>Default value: **false**|
403
404### edgeEffect<sup>10+</sup>
405
406edgeEffect(value: EdgeEffect, options?: EdgeEffectOptions)
407
408Sets the effect used when the scroll boundary is reached.
409
410**Atomic service API**: This API can be used in atomic services since API version 11.
411
412**System capability**: SystemCapability.ArkUI.ArkUI.Full
413
414**Parameters**
415
416| Name               | Type                                                        | Mandatory| Description                                                        |
417| --------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
418| value                 | [EdgeEffect](ts-appendix-enums.md#edgeeffect)                | Yes  | Effect used when the scroll boundary is reached. The spring and shadow effects are supported.<br>Default value: **EdgeEffect.None**|
419| options<sup>11+</sup> | [EdgeEffectOptions](ts-container-scrollable-common.md#edgeeffectoptions11) | No  | Whether to enable the scroll effect when the component content is smaller than the component itself. The value **{ alwaysEnabled: true }** means to enable the scroll effect, and **{ alwaysEnabled: false }** means the opposite.<br>Default value: **{ alwaysEnabled: false }**|
420
421### enableScrollInteraction<sup>10+</sup>
422
423enableScrollInteraction(value: boolean)
424
425Sets whether to support scroll gestures. When this attribute is set to **false**, scrolling by finger or mouse is not supported, but the scrolling controller API is not affected.
426
427**Atomic service API**: This API can be used in atomic services since API version 11.
428
429**System capability**: SystemCapability.ArkUI.ArkUI.Full
430
431**Parameters**
432
433| Name| Type   | Mandatory| Description                               |
434| ------ | ------- | ---- | ----------------------------------- |
435| value  | boolean | Yes  | Whether to support scroll gestures.<br>Default value: **true**|
436
437### nestedScroll<sup>10+</sup>
438
439nestedScroll(value: NestedScrollOptions)
440
441Sets the nested scrolling options. You can set the nested scrolling mode in the forward and backward directions to implement scrolling linkage with the parent component.
442
443**Atomic service API**: This API can be used in atomic services since API version 11.
444
445**System capability**: SystemCapability.ArkUI.ArkUI.Full
446
447**Parameters**
448
449| Name| Type                                                        | Mandatory| Description          |
450| ------ | ------------------------------------------------------------ | ---- | -------------- |
451| value  | [NestedScrollOptions](ts-container-scrollable-common.md#nestedscrolloptions10) | Yes  | Nested scrolling options.|
452
453### friction<sup>10+</sup>
454
455friction(value: number | Resource)
456
457Sets the friction coefficient. It applies only to gestures in the scrolling area, and it affects only indirectly the scroll chaining during the inertial scrolling process. A value less than or equal to 0 evaluates to the default value.
458
459**Atomic service API**: This API can be used in atomic services since API version 11.
460
461**System capability**: SystemCapability.ArkUI.ArkUI.Full
462
463**Parameters**
464
465| Name| Type                                                | Mandatory| Description                                                       |
466| ------ | ---------------------------------------------------- | ---- | ----------------------------------------------------------- |
467| value  | number \| [Resource](ts-types.md#resource) | Yes  | Friction coefficient.<br>Default value: **0.9** for wearable devices and **0.6** for non-wearable devices<br>Since API version 11, the default value for non-wearable devices is **0.7**.<br>Since API version 12, the default value for non-wearable devices is **0.75**.|
468
469### alignItems<sup>12+</sup>
470
471alignItems(alignment: Optional\<GridItemAlignment\>)
472
473Sets the alignment mode of grid items in the grid. For details, see [Example 9](#example-9).
474
475**Atomic service API**: This API can be used in atomic services since API version 12.
476
477**System capability**: SystemCapability.ArkUI.ArkUI.Full
478
479**Parameters**
480
481| Name    | Type  | Mandatory| Description                           |
482| ---------- | ------ | ---- | ------------------------------- |
483| alignment | Optional\<[GridItemAlignment](#griditemalignment12)\> | Yes  | Alignment mode of grid items in the grid.<br>Default value: **GridItemAlignment.DEFAULT**|
484
485## GridItemAlignment<sup>12+</sup>
486
487**Atomic service API**: This API can be used in atomic services since API version 12.
488
489**System capability**: SystemCapability.ArkUI.ArkUI.Full
490
491| Name  | Value| Description                                |
492| ------ |------| -------------------------------------- |
493| DEFAULT  |  0  | Use the default alignment mode of the grid.|
494| STRETCH |  1  | Use the height of the tallest grid item in a row as the height for all other grid items in that row.|
495
496
497> **NOTE**
498>
499> 1. The **STRETCH** option only takes effect in scrollable grids.<br>
500> 2. The **STRETCH** option takes effect only if each grid item in a row is of a regular size (occupying only one row and one column). It is not effective in scenarios where there are grid items spanning across rows or columns.<br>
501> 3. When **STRETCH** is used, only grid items without a set height will adopt the height of the tallest grid item in the current row; the height of grid items with a set height will remain unchanged.<br>
502> 4. When **STRETCH** is used, the grid undergoes an additional layout process, which may incur additional performance overhead.
503
504## GridDirection<sup>8+</sup>
505
506**Atomic service API**: This API can be used in atomic services since API version 11.
507
508**System capability**: SystemCapability.ArkUI.ArkUI.Full
509
510| Name  |Value| Description                                |
511| ------ |------| -------------------------------------- |
512| Row  |  0  | Horizontal layout, where the child components are arranged from left to right as the main axis runs along the rows.|
513| Column |  1  | Vertical layout, where the child components are arranged from top to bottom as the main axis runs down the columns.|
514| RowReverse    |  2  | Reverse horizontal layout, where the child components are arranged from right to left as the main axis runs along the rows.|
515| ColumnReverse   |  3  | Reverse vertical layout, where the child components are arranged from bottom up as the main axis runs down the columns.|
516
517> **NOTE**
518>
519> The default value of the universal attribute [clip](ts-universal-attributes-sharp-clipping.md) is **true** for the **Grid** component.
520
521## Events
522
523In addition to [universal events](ts-universal-events-click.md) and [scrollable component common events](ts-container-scrollable-common.md#events), the following events are also supported.
524
525### onScrollIndex
526
527onScrollIndex(event: (first: number, last: number) => void)
528
529Triggered when the first or last item displayed in the grid changes, that is, when the index of either the first or last item changes. It is triggered once when the grid is initialized.
530
531**Atomic service API**: This API can be used in atomic services since API version 11.
532
533**System capability**: SystemCapability.ArkUI.ArkUI.Full
534
535**Parameters**
536
537| Name            | Type  | Mandatory| Description                            |
538| ------------------ | ------ | ---- | -------------------------------- |
539| first              | number | Yes  | Index of the first item of the grid.|
540| last<sup>10+</sup> | number | Yes  | Index of the last item of the grid.|
541
542### onItemDragStart<sup>8+</sup>
543
544onItemDragStart(event: (event: ItemDragInfo, itemIndex: number) => (() => any) \| void)
545
546Triggered when a grid item starts to be dragged. If **void** is returned, the drag operation cannot be performed.
547
548This event is triggered when the user long presses a grid item.
549
550Drag gesture recognition is also initiated by a long press, and the event processing mechanism prioritizes child component events. Therefore, when the grid item is bound to the long press gesture, it cannot be dragged. In light of this, if both long press and drag operations are required on the grid item, you can use the universal drag event.
551
552**Atomic service API**: This API can be used in atomic services since API version 11.
553
554**System capability**: SystemCapability.ArkUI.ArkUI.Full
555
556**Parameters**
557
558| Name   | Type                                 | Mandatory| Description                  |
559| --------- | ------------------------------------- | ---- | ---------------------- |
560| event     | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes  | Information about the drag point.        |
561| itemIndex | number                                | Yes  | Index of the dragged item.|
562
563### onItemDragEnter<sup>8+</sup>
564
565onItemDragEnter(event: (event: ItemDragInfo) => void)
566
567Triggered when the dragged item enters the drop target of the grid.
568
569**Atomic service API**: This API can be used in atomic services since API version 11.
570
571**System capability**: SystemCapability.ArkUI.ArkUI.Full
572
573**Parameters**
574
575| Name| Type                                 | Mandatory| Description          |
576| ------ | ------------------------------------- | ---- | -------------- |
577| event  | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes  | Information about the drag point.|
578
579### onItemDragMove<sup>8+</sup>
580
581onItemDragMove(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number) => void)
582
583Triggered when the dragged item moves over the drop target of the grid.
584
585**Atomic service API**: This API can be used in atomic services since API version 11.
586
587**System capability**: SystemCapability.ArkUI.ArkUI.Full
588
589**Parameters**
590
591| Name     | Type                                 | Mandatory| Description          |
592| ----------- | ------------------------------------- | ---- | -------------- |
593| event       | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes  | Information about the drag point.|
594| itemIndex   | number                                | Yes  | Initial position of the dragged item.|
595| insertIndex | number                                | Yes  | Index of the position to which the dragged item is dropped.|
596
597### onItemDragLeave<sup>8+</sup>
598
599onItemDragLeave(event: (event: ItemDragInfo, itemIndex: number) => void)
600
601Triggered when the dragged item leaves the drop target of the grid.
602
603**Atomic service API**: This API can be used in atomic services since API version 11.
604
605**System capability**: SystemCapability.ArkUI.ArkUI.Full
606
607**Parameters**
608
609| Name   | Type                                 | Mandatory| Description                      |
610| --------- | ------------------------------------- | ---- | -------------------------- |
611| event     | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes  | Information about the drag point.            |
612| itemIndex | number                                | Yes  | Index of the dragged item.|
613
614### onItemDrop<sup>8+</sup>
615
616onItemDrop(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => void)
617
618Triggered when the dragged item is dropped on the drop target of the grid.
619
620**Atomic service API**: This API can be used in atomic services since API version 11.
621
622**System capability**: SystemCapability.ArkUI.ArkUI.Full
623
624**Parameters**
625
626| Name     | Type                                 | Mandatory| Description          |
627| ----------- | ------------------------------------- | ---- | -------------- |
628| event       | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes  | Information about the drag point.|
629| itemIndex   | number                                | Yes  | Initial position of the dragged item.|
630| insertIndex | number                                | Yes  | Index of the position to which the dragged item is dropped.|
631| isSuccess   | boolean                               | Yes  | Whether the dragged item is successfully dropped.  |
632
633### onScrollBarUpdate<sup>10+</sup>
634
635onScrollBarUpdate(event: (index: number, offset: number) => ComputedBarAttribute)
636
637Triggered when the first item displayed in the grid changes. You can use the callback to set the position and length of the scrollbar.
638
639This API is intended solely for setting the scroll position of the grid. Avoid implementing service logic within this API.
640
641**Atomic service API**: This API can be used in atomic services since API version 11.
642
643**System capability**: SystemCapability.ArkUI.ArkUI.Full
644
645**Parameters**
646
647| Name| Type  | Mandatory| Description                                                        |
648| ------ | ------ | ---- | ------------------------------------------------------------ |
649| index  | number | Yes  | Index of the first item of the grid.                            |
650| offset | number | Yes  | Offset of the displayed first item relative to the start position of the grid, in vp.|
651
652**Return value**
653
654| Type                                                 | Description                |
655| ----------------------------------------------------- | -------------------- |
656| [ComputedBarAttribute](#computedbarattribute10) | Position and length of the scrollbar.|
657
658### onReachStart<sup>10+</sup>
659
660onReachStart(event: () => void)
661
662Triggered when the grid reaches the start position.
663
664This event is triggered once when the grid is initialized and once when the grid scrolls to the start position. If the edge effect is set to a spring effect, this event is triggered once when the swipe passes the initial position, and triggered again when the swipe rebounds back to the initial position.
665
666**Atomic service API**: This API can be used in atomic services since API version 11.
667
668**System capability**: SystemCapability.ArkUI.ArkUI.Full
669
670### onReachEnd<sup>10+</sup>
671
672onReachEnd(event: () => void)
673
674Triggered when the grid reaches the end position.
675
676If the edge effect is set to a spring effect, this event is triggered once when the swipe passes the end position, and triggered again when the swipe rebounds back to the end position.
677
678**Atomic service API**: This API can be used in atomic services since API version 11.
679
680**System capability**: SystemCapability.ArkUI.ArkUI.Full
681
682### onScrollFrameBegin<sup>10+</sup>
683
684onScrollFrameBegin(event: (offset: number, state:  ScrollState) => { offsetRemain: number })
685
686Triggered when the grid starts to scroll. After the amount by which the grid will scroll is passed in, the event handler works out the amount by which the grid needs to scroll based on the real-world situation and returns the result.
687
688**Atomic service API**: This API can be used in atomic services since API version 11.
689
690**System capability**: SystemCapability.ArkUI.ArkUI.Full
691
692**Parameters**
693
694| Name| Type                                                   | Mandatory| Description                      |
695| ------ | ------------------------------------------------------- | ---- | -------------------------- |
696| offset | number                                                  | Yes  | Amount to scroll by, in vp.|
697| state  | [ScrollState](ts-container-list.md#scrollstate) | Yes  | Current scroll state.            |
698
699**Return value**
700
701| Type                    | Description                |
702| ------------------------ | -------------------- |
703| { offsetRemain: number } | Actual amount by which the grid scrolls, in vp.|
704
705### onScrollStart<sup>10+</sup>
706
707onScrollStart(event: () => void)
708
709Triggered when the grid starts scrolling initiated by the user's finger dragging the grid or its scrollbar. This event is also triggered when the animation contained in the scrolling triggered by [Scroller](ts-container-scroll.md#scroller) starts.
710
711**Atomic service API**: This API can be used in atomic services since API version 11.
712
713**System capability**: SystemCapability.ArkUI.ArkUI.Full
714
715### onScrollStop<sup>10+</sup>
716
717onScrollStop(event: () => void)
718
719Triggered when the grid stops scrolling after the user's finger leaves the screen. This event is also triggered when the animation contained in the scrolling triggered by [Scroller](ts-container-scroll.md#scroller) stops.
720
721**Atomic service API**: This API can be used in atomic services since API version 11.
722
723**System capability**: SystemCapability.ArkUI.ArkUI.Full
724
725### onScroll<sup>(deprecated)</sup>
726onScroll(event: (scrollOffset: number, scrollState: [ScrollState](ts-container-list.md#scrollstate)) => void)
727
728Triggered when the grid scrolls.
729
730This API is supported since API version 10 and deprecated since API version 12. You are advised to use [onDidScroll](ts-container-scrollable-common.md#ondidscroll12) instead.
731
732**Atomic service API**: This API can be used in atomic services since API version 11.
733
734**System capability**: SystemCapability.ArkUI.ArkUI.Full
735
736**Parameters**
737
738| Name| Type| Mandatory| Description|
739| ------ | ------ | ------ | ------|
740| scrollOffset | number | Yes| Scroll offset of each frame. The offset is positive when the grid is scrolled up and negative when the grid is scrolled down.<br>Unit: vp|
741| scrollState | [ScrollState](ts-container-list.md#scrollstate) | Yes| Current scroll state.|
742
743## ComputedBarAttribute<sup>10+</sup>
744
745**Atomic service API**: This API can be used in atomic services since API version 11.
746
747**System capability**: SystemCapability.ArkUI.ArkUI.Full
748
749| Name        | Type        | Read Only| Optional|   Description        |
750| ----------- | ------------ | ---- | ---- | ---------- |
751| totalOffset | number | No| No|  Total offset of the grid content relative to the display area, in px.   |
752| totalLength   | number | No| No|  Total length of the grid content, in px.   |
753
754## Example
755
756### Example 1
757
758This example shows a grid with fixed number of rows and columns, for which you can use **onGetRectByIndex** in **GridLayoutOptions** to specify the position and size of grid items.
759
760```ts
761// xxx.ets
762@Entry
763@Component
764struct GridExample {
765  @State numbers1: String[] = ['0', '1', '2', '3', '4']
766  @State numbers2: String[] = ['0', '1','2','3','4','5']
767
768  layoutOptions3: GridLayoutOptions = {
769    regularSize: [1, 1],
770    onGetRectByIndex: (index: number) => {
771      if (index == 0)
772        return [0, 0, 1, 1]
773      else if(index==1)
774        return [0, 1, 2, 2]
775      else if(index==2)
776        return [0 ,3 ,3 ,3]
777      else if(index==3)
778        return [3, 0, 3, 3]
779      else if(index==4)
780        return [4, 3, 2, 2]
781      else
782        return [5, 5, 1, 1]
783    }
784  }
785
786  build() {
787    Column({ space: 5 }) {
788      Grid() {
789        ForEach(this.numbers1, (day: string) => {
790          ForEach(this.numbers1, (day: string) => {
791            GridItem() {
792              Text(day)
793                .fontSize(16)
794                .backgroundColor(0xF9CF93)
795                .width('100%')
796                .height('100%')
797                .textAlign(TextAlign.Center)
798            }
799          }, (day: string) => day)
800        }, (day: string) => day)
801      }
802      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
803      .rowsTemplate('1fr 1fr 1fr 1fr 1fr')
804      .columnsGap(10)
805      .rowsGap(10)
806      .width('90%')
807      .backgroundColor(0xFAEEE0)
808      .height(300)
809
810      Text('Use of GridLayoutOptions: onGetRectByIndex').fontColor(0xCCCCCC).fontSize(9).width('90%')
811
812      Grid(undefined, this.layoutOptions3) {
813        ForEach(this.numbers2, (day: string) => {
814          GridItem() {
815            Text(day)
816              .fontSize(16)
817              .backgroundColor(0xF9CF93)
818              .width('100%')
819              .height("100%")
820              .textAlign(TextAlign.Center)
821          }
822          .height("100%")
823          .width('100%')
824        }, (day: string) => day)
825      }
826      .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
827      .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
828      .columnsGap(10)
829      .rowsGap(10)
830      .width('90%')
831      .backgroundColor(0xFAEEE0)
832      .height(300)
833    }.width('100%').margin({ top: 5 })
834  }
835}
836```
837
838![en-us_image_0000001219744183](figures/en-us_image_0000001219744183.gif)
839
840### Example 2
841
842This example shows a scrollable grid with all its scrolling attributes and events specified.
843
844```ts
845// xxx.ets
846@Entry
847@Component
848struct GridExample {
849  @State numbers: String[] = ['0', '1', '2', '3', '4']
850  scroller: Scroller = new Scroller()
851  @State gridPosition: number = 0 // 0 indicates scrolling to the top of the grid, 1 indicates scrolling to the center, and 2 indicates scrolling to the bottom.
852
853  build() {
854    Column({ space: 5 }) {
855      Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
856      Grid(this.scroller) {
857        ForEach(this.numbers, (day: string) => {
858          ForEach(this.numbers, (day: string) => {
859            GridItem() {
860              Text(day)
861                .fontSize(16)
862                .backgroundColor(0xF9CF93)
863                .width('100%')
864                .height(80)
865                .textAlign(TextAlign.Center)
866            }
867          }, (day: string) => day)
868        }, (day: string) => day)
869      }
870      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
871      .columnsGap(10)
872      .rowsGap(10)
873      .friction(0.6)
874      .enableScrollInteraction(true)
875      .supportAnimation(false)
876      .multiSelectable(false)
877      .edgeEffect(EdgeEffect.Spring)
878      .scrollBar(BarState.On)
879      .scrollBarColor(Color.Grey)
880      .scrollBarWidth(4)
881      .width('90%')
882      .backgroundColor(0xFAEEE0)
883      .height(300)
884      .onScrollIndex((first: number, last: number) => {
885        console.info(first.toString())
886        console.info(last.toString())
887      })
888      .onScrollBarUpdate((index: number, offset: number) => {
889        console.info("XXX" + 'Grid onScrollBarUpdate,index : ' + index.toString() + ",offset" + offset.toString())
890        return { totalOffset: (index / 5) * (80 + 10) - offset, totalLength: 80 * 5 + 10 * 4 }
891      }) // The sample code applies only to the current data source. If the data source changes, modify the code or delete this attribute.
892      .onDidScroll((scrollOffset: number, scrollState: ScrollState) => {
893        console.info(scrollOffset.toString())
894        console.info(scrollState.toString())
895      })
896      .onScrollStart(() => {
897        console.info("XXX" + "Grid onScrollStart")
898      })
899      .onScrollStop(() => {
900        console.info("XXX" + "Grid onScrollStop")
901      })
902      .onReachStart(() => {
903        this.gridPosition = 0
904        console.info("XXX" + "Grid onReachStart")
905      })
906      .onReachEnd(() => {
907        this.gridPosition = 2
908        console.info("XXX" + "Grid onReachEnd")
909      })
910
911      Button('next page')
912        .onClick(() => {// Click to go to the next page.
913          this.scroller.scrollPage({ next: true })
914        })
915    }.width('100%').margin({ top: 5 })
916  }
917}
918```
919
920![scrollerExample2](figures/scrollerExample2.gif)
921
922### Example 3
923
924This example uses **irregularIndexes** and **onGetIrregularSizeByIndex** in **GridLayoutOptions**.
925
926```ts
927// xxx.ets
928@Entry
929@Component
930struct GridExample {
931  @State numbers: String[] = ['0', '1', '2', '3', '4']
932  scroller: Scroller = new Scroller()
933  layoutOptions1: GridLayoutOptions = {
934    regularSize: [1, 1],        // Only [1, 1] is supported.
935    irregularIndexes: [0, 6], // The grid item whose indexes are 0 and 6 occupies one row.
936  }
937
938  layoutOptions2: GridLayoutOptions = {
939    regularSize: [1, 1],
940    irregularIndexes: [0, 7], // The number of columns occupied by the grid item whose indexes are 0 and 7 is specified by onGetIrregularSizeByIndex.
941    onGetIrregularSizeByIndex: (index: number) => {
942      if (index === 0) {
943        return [1, 5]
944      }
945      return [1, index % 6 + 1]
946    }
947  }
948
949  build() {
950    Column({ space: 5 }) {
951      Grid(this.scroller, this.layoutOptions1) {
952        ForEach(this.numbers, (day: string) => {
953          ForEach(this.numbers, (day: string) => {
954            GridItem() {
955              Text(day)
956                .fontSize(16)
957                .backgroundColor(0xF9CF93)
958                .width('100%')
959                .height(80)
960                .textAlign(TextAlign.Center)
961            }.selectable(false)
962          }, (day: string) => day)
963        }, (day: string) => day)
964      }
965      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
966      .columnsGap(10)
967      .rowsGap(10)
968      .multiSelectable(true)
969      .scrollBar(BarState.Off)
970      .width('90%')
971      .backgroundColor(0xFAEEE0)
972      .height(300)
973
974      Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
975      // The grid does not scroll, and undefined is used to reserve space.
976      Grid(undefined, this.layoutOptions2) {
977        ForEach(this.numbers, (day: string) => {
978          ForEach(this.numbers, (day: string) => {
979            GridItem() {
980              Text(day)
981                .fontSize(16)
982                .backgroundColor(0xF9CF93)
983                .width('100%')
984                .height(80)
985                .textAlign(TextAlign.Center)
986            }
987          }, (day: string) => day)
988        }, (day: string) => day)
989      }
990      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
991      .columnsGap(10)
992      .rowsGap(10)
993      .scrollBar(BarState.Off)
994      .width('90%')
995      .backgroundColor(0xFAEEE0)
996      .height(300)
997    }.width('100%').margin({ top: 5 })
998  }
999}
1000```
1001
1002![gridLayoutOptions](figures/gridLayoutOptions.gif)
1003
1004### Example 4
1005
1006Example of using **nestedScroll** and **onScrollFrameBegin**:
1007
1008```ts
1009@Entry
1010@Component
1011struct GridExample {
1012  @State colors: number[] = [0xFFC0CB, 0xDA70D6, 0x6B8E23, 0x6A5ACD, 0x00FFFF, 0x00FF7F]
1013  @State numbers: number[] = []
1014  @State translateY: number = 0
1015  private scroller: Scroller = new Scroller()
1016  private gridScroller: Scroller = new Scroller()
1017  private touchDown: boolean = false
1018  private listTouchDown: boolean = false
1019  private scrolling: boolean = false
1020
1021  aboutToAppear() {
1022    for (let i = 0; i < 100; i++) {
1023      this.numbers.push(i)
1024    }
1025  }
1026
1027  build() {
1028    Stack() {
1029      Column() {
1030        Row() {
1031          Text('Head')
1032        }
1033
1034        Column() {
1035          List({ scroller: this.scroller }) {
1036            ListItem() {
1037              Grid() {
1038                GridItem() {
1039                  Text('GoodsTypeList1')
1040                }
1041                .backgroundColor(this.colors[0])
1042                .columnStart(0)
1043                .columnEnd(1)
1044
1045                GridItem() {
1046                  Text('GoodsTypeList2')
1047                }
1048                .backgroundColor(this.colors[1])
1049                .columnStart(0)
1050                .columnEnd(1)
1051
1052                GridItem() {
1053                  Text('GoodsTypeList3')
1054                }
1055                .backgroundColor(this.colors[2])
1056                .columnStart(0)
1057                .columnEnd(1)
1058
1059                GridItem() {
1060                  Text('GoodsTypeList4')
1061                }
1062                .backgroundColor(this.colors[3])
1063                .columnStart(0)
1064                .columnEnd(1)
1065
1066                GridItem() {
1067                  Text('GoodsTypeList5')
1068                }
1069                .backgroundColor(this.colors[4])
1070                .columnStart(0)
1071                .columnEnd(1)
1072              }
1073              .scrollBar(BarState.Off)
1074              .columnsGap(15)
1075              .rowsGap(10)
1076              .rowsTemplate('1fr 1fr 1fr 1fr 1fr')
1077              .columnsTemplate('1fr')
1078              .width('100%')
1079              .height(200)
1080            }
1081
1082            ListItem() {
1083              Grid(this.gridScroller) {
1084                ForEach(this.numbers, (item: number) => {
1085                  GridItem() {
1086                    Text(item + '')
1087                      .fontSize(16)
1088                      .backgroundColor(0xF9CF93)
1089                      .width('100%')
1090                      .height('100%')
1091                      .textAlign(TextAlign.Center)
1092                  }
1093                  .width('100%')
1094                  .height(40)
1095                  .shadow({ radius: 10, color: '#909399', offsetX: 1, offsetY: 1 })
1096                  .borderRadius(10)
1097                  .translate({ x: 0, y: this.translateY })
1098                }, (item: string) => item)
1099              }
1100              .columnsTemplate('1fr 1fr')
1101              .friction(0.3)
1102              .columnsGap(15)
1103              .rowsGap(10)
1104              .scrollBar(BarState.Off)
1105              .width('100%')
1106              .height('100%')
1107              .layoutDirection(GridDirection.Column)
1108              .nestedScroll({
1109                scrollForward: NestedScrollMode.PARENT_FIRST,
1110                scrollBackward: NestedScrollMode.SELF_FIRST
1111              })
1112              .onTouch((event: TouchEvent) => {
1113                if (event.type == TouchType.Down) {
1114                  this.listTouchDown = true
1115                } else if (event.type == TouchType.Up) {
1116                  this.listTouchDown = false
1117                }
1118              })
1119            }
1120          }
1121          .scrollBar(BarState.Off)
1122          .edgeEffect(EdgeEffect.None)
1123          .onTouch((event: TouchEvent) => {
1124            if (event.type == TouchType.Down) {
1125              this.touchDown = true
1126            } else if (event.type == TouchType.Up) {
1127              this.touchDown = false
1128            }
1129          })
1130          .onScrollFrameBegin((offset: number, state: ScrollState) => {
1131            if (this.scrolling && offset > 0) {
1132              let newOffset = this.scroller.currentOffset().yOffset
1133              if (newOffset >= 590) {
1134                this.gridScroller.scrollBy(0, offset)
1135                return { offsetRemain: 0 }
1136              } else if (newOffset + offset > 590) {
1137                this.gridScroller.scrollBy(0, newOffset + offset - 590)
1138                return { offsetRemain: 590 - newOffset }
1139              }
1140            }
1141            return { offsetRemain: offset }
1142          })
1143          .onScrollStart(() => {
1144            if (this.touchDown && !this.listTouchDown) {
1145              this.scrolling = true
1146            }
1147          })
1148          .onScrollStop(() => {
1149            this.scrolling = false
1150          })
1151        }
1152        .width('100%')
1153        .height('100%')
1154        .padding({ left: 10, right: 10 })
1155      }
1156
1157      Row() {
1158        Text('Top')
1159          .width(30)
1160          .height(30)
1161          .borderRadius(50)
1162      }
1163      .padding(5)
1164      .borderRadius(50)
1165      .backgroundColor('#ffffff')
1166      .shadow({ radius: 10, color: '#909399', offsetX: 1, offsetY: 1 })
1167      .margin({ right: 22, bottom: 15 })
1168      .onClick(() => {
1169        this.scroller.scrollTo({ xOffset: 0, yOffset: 0 })
1170        this.gridScroller.scrollTo({ xOffset: 0, yOffset: 0 })
1171      })
1172    }
1173    .align(Alignment.BottomEnd)
1174  }
1175}
1176```
1177
1178![nestedScrollExample4](figures/nestedScrollExample4.gif)
1179
1180### Example 5
1181
11821.  Set **editMode\(true\)** to enable edit mode, where the user can drag the grid items.
11832.  In the [onItemDragStart](#onitemdragstart8) callback, set the image to be displayed during dragging.
11843.  Through [onItemDrop](#onitemdrop8), obtain the initial position of the dragged item and the position to which the dragged item will be dropped. Through [onItemDrop](#onitemdrop8), complete the array position exchange logic.
1185
1186> **NOTE**
1187>
1188> The drag and drop action is not displayed in the preview.
1189
1190```ts
1191@Entry
1192@Component
1193struct GridExample {
1194  @State numbers: string[] = []
1195  scroller: Scroller = new Scroller()
1196  @State text: string = 'drag'
1197
1198  @Builder pixelMapBuilder () { // Style for the drag event.
1199    Column() {
1200      Text(this.text)
1201        .fontSize(16)
1202        .backgroundColor(0xF9CF93)
1203        .width(80)
1204        .height(80)
1205        .textAlign(TextAlign.Center)
1206    }
1207  }
1208
1209  aboutToAppear() {
1210    for (let i = 1;i <= 15; i++) {
1211      this.numbers.push(i + '')
1212    }
1213  }
1214
1215  changeIndex(index1: number, index2: number) { // Exchange the array position.
1216    let temp: string;
1217    temp = this.numbers[index1];
1218    this.numbers[index1] = this.numbers[index2];
1219    this.numbers[index2] = temp;
1220  }
1221
1222  build() {
1223    Column({ space: 5 }) {
1224      Grid(this.scroller) {
1225        ForEach(this.numbers, (day: string) => {
1226          GridItem() {
1227            Text(day)
1228              .fontSize(16)
1229              .backgroundColor(0xF9CF93)
1230              .width(80)
1231              .height(80)
1232              .textAlign(TextAlign.Center)
1233          }
1234        })
1235      }
1236      .columnsTemplate('1fr 1fr 1fr')
1237      .columnsGap(10)
1238      .rowsGap(10)
1239      .width('90%')
1240      .backgroundColor(0xFAEEE0)
1241      .height(300)
1242      .editMode(true) // Enable edit mode, where the user can drag the grid items.
1243      .onItemDragStart((event: ItemDragInfo, itemIndex: number) => { // Triggered when a grid item starts to be dragged.
1244        this.text = this.numbers[itemIndex]
1245        return this.pixelMapBuilder() // Set the image to be displayed during dragging.
1246      })
1247      .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => { // Triggered when the dragged item is dropped on the drop target of the grid.
1248        // If isSuccess is set to false, the item is dropped outside of the grid. If the value of insertIndex is greater than that of length, an item adding event occurs.
1249        if (!isSuccess || insertIndex >= this.numbers.length) {
1250          return
1251        }
1252        console.info('beixiang' + itemIndex + '', insertIndex + '') // itemIndex indicates the initial position of the dragged item. insertIndex indicates the position to which the dragged item will be dropped.
1253        this.changeIndex(itemIndex, insertIndex)
1254      })
1255    }.width('100%').margin({ top: 5 })
1256  }
1257}
1258```
1259
1260Below are some examples.
1261
1262Below shows how the grid looks when dragging of grid items starts.
1263
1264![gridDrag](figures/gridDrag.png)
1265
1266Below shows how the grid looks when dragging of grid items is in progress.
1267
1268![gridDrag](figures/gridDrag1.png)
1269
1270Below shows how the grid looks after grid item 1 and grid item 6 swap their positions.
1271
1272![gridDrag](figures/gridDrag2.png)
1273
1274### Example 6
1275
1276Example of using **layoutDirection**, **maxcount**, **minCount**, and **cellLength**:
1277
1278```ts
1279@Entry
1280@Component
1281struct GridExample {
1282  @State numbers: string[] = []
1283
1284  aboutToAppear() {
1285    for (let i = 1; i <= 30; i++) {
1286      this.numbers.push(i + '')
1287    }
1288  }
1289
1290  build() {
1291    Scroll() {
1292      Column({ space: 5 }) {
1293        Blank()
1294        Text('The layoutDirection, maxcount, minCount, and cellLength parameters take effect only when neither rowsTemplate nor columnsTemplate is set.')
1295          .fontSize(15).fontColor(0xCCCCCC).width('90%')
1296        Grid() {
1297          ForEach(this.numbers, (day: string) => {
1298            GridItem() {
1299              Text(day).fontSize(16).backgroundColor(0xF9CF93)
1300            }.width(40).height(80).borderWidth(2).borderColor(Color.Red)
1301          }, (day: string) => day)
1302        }
1303        .height(300)
1304        .columnsGap(10)
1305        .rowsGap(10)
1306        .backgroundColor(0xFAEEE0)
1307        .maxCount(6)
1308        .minCount(2)
1309        .cellLength(0)
1310        .layoutDirection(GridDirection.Row)
1311      }
1312      .width('90%').margin({ top: 5, left: 5, right: 5 })
1313      .align(Alignment.Center)
1314    }
1315  }
1316}
1317```
1318
1319![cellLength](figures/cellLength.gif)
1320
1321### Example 7
1322
1323This example demonstrates how to adjust the number of columns in the grid with a pinch gesture using two fingers.
1324
1325```ts
1326// xxx.ets
1327@Entry
1328@Component
1329struct GridExample {
1330  @State numbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19']
1331  @State columns: number = 2
1332
1333  aboutToAppear() {
1334    let lastCount = AppStorage.get<number>('columnsCount')
1335    if (typeof lastCount != 'undefined') {
1336      this.columns = lastCount
1337    }
1338  }
1339
1340  build() {
1341    Column({ space: 5 }) {
1342      Row() {
1343        Text('Pinch to change the number of columns')
1344          .height('5%')
1345          .margin({ top: 10, left: 20 })
1346      }
1347
1348      Grid() {
1349        ForEach(this.numbers, (day: string) => {
1350          ForEach(this.numbers, (day: string) => {
1351            GridItem() {
1352              Text(day)
1353                .fontSize(16)
1354                .backgroundColor(0xF9CF93)
1355                .width('100%')
1356                .height(80)
1357                .textAlign(TextAlign.Center)
1358            }
1359          }, (day: string) => day)
1360        }, (day: string) => day)
1361      }
1362      .columnsTemplate('1fr '.repeat(this.columns))
1363      .columnsGap(10)
1364      .rowsGap(10)
1365      .width('90%')
1366      .scrollBar(BarState.Off)
1367      .backgroundColor(0xFAEEE0)
1368      .height('100%')
1369      .cachedCount(3)
1370      // Switching the number of columns triggers a reordering animation for the item positions.
1371      .animation({
1372        duration: 300,
1373        curve: Curve.Smooth
1374      })
1375      .priorityGesture(
1376        PinchGesture()
1377          .onActionEnd((event: GestureEvent) => {
1378            console.info('end scale:' + event.scale)
1379            // When a user performs a pinch-to-zoom gesture by moving their fingers apart, and the number of columns decreases to a certain threshold (in this case, 2), it will cause the items to enlarge.
1380            if (event.scale > 2) {
1381              this.columns--
1382            } else if (event.scale < 0.6) {
1383              this.columns++
1384            }
1385            // You can set the maximum and minimum number of columns based on the device screen width. Here, the minimum number of columns is 1, and the maximum number of columns is 4.
1386            this.columns = Math.min(4, Math.max(1, this.columns));
1387            AppStorage.setOrCreate<number>('columnsCount', this.columns)
1388          })
1389      )
1390    }.width('100%').margin({ top: 5 })
1391  }
1392}
1393```
1394
1395![pinch](figures/grid-pinch.gif)
1396
1397### Example 8
1398This example shows the usage of **auto-fill**, **auto-fit**, and **auto-stretch** in the [columnsTemplate](#columnstemplate) attribute.
1399
1400```ts
1401@Entry
1402@Component
1403struct GridColumnsTemplate {
1404  data: number[] = [0, 1, 2, 3, 4, 5]
1405  data1: number[] = [0, 1, 2, 3, 4, 5]
1406  data2: number[] = [0, 1, 2, 3, 4, 5]
1407
1408  build() {
1409    Column({ space: 10 }) {
1410      Text('auto-fill auto-calculates the number of columns based on the set column width').width('90%')
1411      Grid() {
1412        ForEach(this.data, (item: number) => {
1413          GridItem() {
1414            Text('N' + item).height(80)
1415          }
1416          .backgroundColor(Color.Orange)
1417        })
1418      }
1419      .width('90%')
1420      .border({ width: 1, color: Color.Black })
1421      .columnsTemplate('repeat(auto-fill, 70)')
1422      .columnsGap(10)
1423      .rowsGap(10)
1424      .height(150)
1425
1426      Text('auto-fit calculates the number of columns based on the specified column width, and then any remaining space is evenly distributed across all columns').width('90%')
1427      Grid() {
1428        ForEach(this.data1, (item: number) => {
1429          GridItem() {
1430            Text('N' + item).height(80)
1431          }
1432          .backgroundColor(Color.Orange)
1433        })
1434      }
1435      .width('90%')
1436      .border({ width: 1, color: Color.Black })
1437      .columnsTemplate('repeat(auto-fit, 70)')
1438      .columnsGap(10)
1439      .rowsGap(10)
1440      .height(150)
1441
1442      Text('auto-stretch calculates the number of columns based on the specified column width, and then any remaining space is evenly distributed into the gaps between columns').width('90%')
1443      Grid() {
1444        ForEach(this.data2, (item: number) => {
1445          GridItem() {
1446            Text('N' + item).height(80)
1447          }
1448          .backgroundColor(Color.Orange)
1449        })
1450      }
1451      .width('90%')
1452      .border({ width: 1, color: Color.Black })
1453      .columnsTemplate('repeat(auto-stretch, 70)')
1454      .columnsGap(10)
1455      .rowsGap(10)
1456      .height(150)
1457    }
1458    .width('100%')
1459    .height('100%')
1460  }
1461}
1462```
1463
1464![gridColumnsTemplate](figures/gridColumnsTemplate.png)
1465
1466### Example 9
1467This example implements a grid that contains two columns. The grid item in each column consists of two **Column** components with determined heights and one **Text** component with an undetermined height.
1468
1469By default, the heights of the left and right grid items may differ; however, after the grid's **alignItems** attribute is set to **GridItemAlignment.STRETCH**, the grid item with a shorter height in a row will adopt the height of the taller grid item, aligning their heights within the same row.
1470
1471```ts
1472@Entry
1473@Component
1474struct Index {
1475  @State data: number[] = [];
1476  @State items: number[] = [];
1477
1478  aboutToAppear(): void {
1479    for (let i = 0; i < 100; i++) {
1480      this.data.push(i)
1481      this.items.push(this.getSize())
1482    }
1483  }
1484
1485  getSize() {
1486    let ret = Math.floor(Math.random() * 5)
1487    return Math.max(1, ret)
1488  }
1489
1490  build() {
1491    Column({ space: 10 }) {
1492      Text('Grid alignItems sample code')
1493
1494      Grid() {
1495        ForEach(this.data, (item: number) => {
1496          // GridItem and Column components, when left without explicitly set heights, will by default adapt to the size of their child components. With alignItems set to STRETCH, they will instead take on the height of the tallest component in the current row.
1497          // If the height is explicitly set, the component maintains the defined height and will not follow the height of the tallest component in the current row.
1498          GridItem() {
1499            Column() {
1500              Column().height(100).backgroundColor('#D5D5D5').width('100%')
1501              // The Text component in the center is set with flexGrow(1) to automatically fill the available space within the parent component.
1502              Text('This is a piece of text.'.repeat(this.items[item]))
1503                .flexGrow(1).width('100%').align(Alignment.TopStart)
1504                .backgroundColor('#F7F7F7')
1505              Column().height(50).backgroundColor('#707070').width('100%')
1506            }
1507          }
1508          .border({ color: Color.Black, width: 1 })
1509        })
1510      }
1511      .columnsGap(10)
1512      .rowsGap(5)
1513      .columnsTemplate('1fr 1fr')
1514      .width('80%')
1515      .height('100%')
1516      // When the grid has its alignItems attribute set to STRETCH, it adjusts the height of all grid items in a row to match the height of the tallest grid item in that row.
1517      .alignItems(GridItemAlignment.STRETCH)
1518      .scrollBar(BarState.Off)
1519    }
1520    .height('100%')
1521    .width('100%')
1522  }
1523}
1524
1525```
1526![gridAlignItems](figures/gridAlignItems.png)
1527
1528### Example 10
1529
1530```ts
1531// xxx.ets
1532// This example demonstrates how to implement a Grid component with an edge fading effect and set the length of the fading edge.
1533import { LengthMetrics } from '@kit.ArkUI'
1534@Entry
1535@Component
1536struct GridExample {
1537  @State numbers: String[] = ['0', '1', '2', '3', '4']
1538  @State rowNumbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
1539  scroller: Scroller = new Scroller()
1540
1541  build() {
1542    Column({ space: 5 }) {
1543      Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
1544      Grid(this.scroller) {
1545        ForEach(this.rowNumbers, (day: string) => {
1546          ForEach(this.numbers, (day: string) => {
1547            GridItem() {
1548              Text(day)
1549                .fontSize(16)
1550                .backgroundColor(0xF9CF93)
1551                .width('100%')
1552                .height(80)
1553                .textAlign(TextAlign.Center)
1554            }
1555          }, (day: string) => day)
1556        }, (day: string) => day)
1557      }
1558      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
1559      .columnsGap(10)
1560      .rowsGap(20)
1561      .height('90%')
1562      .fadingEdge(true,{fadingEdgeLength:LengthMetrics.vp(80)})
1563
1564    }.width('100%').margin({ top: 5 })
1565  }
1566}
1567```
1568
1569![fadingEdge_grid](figures/fadingEdge_grid.gif)