• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
38Creates a **Grid** component.
39
40**Atomic service API**: This API can be used in atomic services since API version 11.
41
42**System capability**: SystemCapability.ArkUI.ArkUI.Full
43
44**Parameters**
45
46| Name  | Type                                   | Mandatory| Description                                                    |
47| -------- | ------------------------------------------- | ---- | ------------------------------------------------------------ |
48| 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 [ArcList](ts-container-arclist.md), [List](ts-container-list.md), [Grid](ts-container-grid.md), or [Scroll](ts-container-scroll.md).|
49| layoutOptions<sup>10+</sup> | [GridLayoutOptions](#gridlayoutoptions10) | No| Grid layout options.|
50
51## GridLayoutOptions<sup>10+</sup>
52
53Defines the grid layout options. In this API, **irregularIndexes** and **onGetIrregularSizeByIndex** can be used for grids where either **rowsTemplate** or **columnsTemplate** is set. These properties allow you to specify an index array and set the number of rows and columns to be occupied by a grid item at the specified index. For details about the usage, see [Example 3](#example-3-implementing-a-scrollable-grid-with-grid-items-spanning-rows-and-columns). On the other hand, **onGetRectByIndex** can be used for grids where both **rowsTemplate** and **columnsTemplate** are set. It allows you to specify the position and size for the grid item at the specified index. For details about the usage, see [Example 1](#example-1-creating-a-fixed-row-and-column-grid-layout).
54
55**System capability**: SystemCapability.ArkUI.ArkUI.Full
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-component-general-attributes.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 details about the effect, see [Example 8](#example-8-using-adaptive-column-count-settings).
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**<br>Value range: [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**<br>Value range: [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)<br>A number value indicates a HEX color in RGB or ARGB format, for example, **0xffffff**. A string value indicates a color in RGB or ARGB format, for example, **'#ffffff'**.|
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<br>If this parameter is set to a value less than or equal to 0, the default value is used. The value **0** means not to show the scrollbar.|
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. <!--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: the number of rows visible on the screen for vertical scrolling, or the number of columns visible on the screen for horizontal scrolling. The maximum value is 16.<br>Value range: [0, +∞).<br>Values less than 0 are treated as **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 cached 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 cached (preloaded).<br>Default value: the number of rows visible on the screen for vertical scrolling, or the number of columns visible on the screen for horizontal scrolling. The maximum value is 16.<br>Value range: [0, +∞).<br>Values less than 0 are treated as **1**.|
276| show  | boolean | Yes  | Whether to display the preloaded nodes.<br> Default value: **false** (the preloaded nodes are not displayed).|
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** (the edit mode is disabled).|
293
294### layoutDirection<sup>8+</sup>
295
296layoutDirection(value: GridDirection)
297
298Sets the main axis layout 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 layout 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
342If the value of **minCount** is greater than that of **maxCount**, both **minCount** and **maxCount** are treated as using their default values.
343
344**Atomic service API**: This API can be used in atomic services since API version 11.
345
346**System capability**: SystemCapability.ArkUI.ArkUI.Full
347
348**Parameters**
349
350| Name| Type  | Mandatory| Description                                  |
351| ------ | ------ | ---- | -------------------------------------- |
352| value  | number | Yes  | Minimum number of rows or columns that can be displayed.<br>Default value: **1**|
353
354### cellLength<sup>8+</sup>
355
356cellLength(value: number)
357
358Sets the height per row or width per column.
359
360When **layoutDirection** is **Row** or **RowReverse**, the value indicates the height per row.
361
362When **layoutDirection** is **Column** or **ColumnReverse**, the value indicates the width per column.
363
364**Atomic service API**: This API can be used in atomic services since API version 11.
365
366**System capability**: SystemCapability.ArkUI.ArkUI.Full
367
368**Parameters**
369
370| Name| Type  | Mandatory| Description                                                   |
371| ------ | ------ | ---- | ------------------------------------------------------- |
372| value  | number | Yes  | Height per row or width per column.<br>Default value: size of the first element<br>Unit: vp<br>Value range: [0, +∞).<br>If a value less than 0 is set, the default value is used.|
373
374### multiSelectable<sup>8+</sup>
375
376multiSelectable(value: boolean)
377
378Whether 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).
379
380**Atomic service API**: This API can be used in atomic services since API version 11.
381
382**System capability**: SystemCapability.ArkUI.ArkUI.Full
383
384**Parameters**
385
386| Name| Type   | Mandatory| Description                                                        |
387| ------ | ------- | ---- | ------------------------------------------------------------ |
388| value  | boolean | Yes  | Whether to enable multiselect.<br>Default value: **false**<br>**false**: Multiselect is disabled. **true**: Multiselect is disabled.|
389
390### supportAnimation<sup>8+</sup>
391
392supportAnimation(value: boolean)
393
394Sets 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.
395
396**Atomic service API**: This API can be used in atomic services since API version 11.
397
398**System capability**: SystemCapability.ArkUI.ArkUI.Full
399
400**Parameters**
401
402| Name| Type   | Mandatory| Description                            |
403| ------ | ------- | ---- | -------------------------------- |
404| value  | boolean | Yes  | Whether to enable animation.<br>Default value: **false** (animation is disabled).|
405
406### edgeEffect<sup>10+</sup>
407
408edgeEffect(value: EdgeEffect, options?: EdgeEffectOptions)
409
410Sets the effect used when the scroll boundary is reached.
411
412**Atomic service API**: This API can be used in atomic services since API version 11.
413
414**System capability**: SystemCapability.ArkUI.ArkUI.Full
415
416**Parameters**
417
418| Name               | Type                                                        | Mandatory| Description                                                        |
419| --------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
420| 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**|
421| 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 }**|
422
423### enableScrollInteraction<sup>10+</sup>
424
425enableScrollInteraction(value: boolean)
426
427Sets 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.
428
429**Atomic service API**: This API can be used in atomic services since API version 11.
430
431**System capability**: SystemCapability.ArkUI.ArkUI.Full
432
433**Parameters**
434
435| Name| Type   | Mandatory| Description                               |
436| ------ | ------- | ---- | ----------------------------------- |
437| value  | boolean | Yes  | Whether to support scroll gestures.<br>Default value: **true**|
438
439### nestedScroll<sup>10+</sup>
440
441nestedScroll(value: NestedScrollOptions)
442
443Sets 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.
444
445**Atomic service API**: This API can be used in atomic services since API version 11.
446
447**System capability**: SystemCapability.ArkUI.ArkUI.Full
448
449**Parameters**
450
451| Name| Type                                                        | Mandatory| Description          |
452| ------ | ------------------------------------------------------------ | ---- | -------------- |
453| value  | [NestedScrollOptions](ts-container-scrollable-common.md#nestedscrolloptions10) | Yes  | Nested scrolling options.|
454
455### friction<sup>10+</sup>
456
457friction(value: number | Resource)
458
459Sets 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.
460
461**Atomic service API**: This API can be used in atomic services since API version 11.
462
463**System capability**: SystemCapability.ArkUI.ArkUI.Full
464
465**Parameters**
466
467| Name| Type                                                | Mandatory| Description                                                       |
468| ------ | ---------------------------------------------------- | ---- | ----------------------------------------------------------- |
469| 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**.<br>Value range: (0, +∞). If this parameter is set to a value less than or equal to 0, the default value is used.|
470
471### alignItems<sup>12+</sup>
472
473alignItems(alignment: Optional\<GridItemAlignment\>)
474
475Sets the alignment mode of grid items in the grid. For details about the usage, see [Example 9](#example-9-setting-grid-item-heights-based-on-the-tallest-item-in-the-current-row).
476
477**Atomic service API**: This API can be used in atomic services since API version 12.
478
479**System capability**: SystemCapability.ArkUI.ArkUI.Full
480
481**Parameters**
482
483| Name    | Type  | Mandatory| Description                           |
484| ---------- | ------ | ---- | ------------------------------- |
485| alignment | Optional\<[GridItemAlignment](#griditemalignment12)\> | Yes  | Alignment mode of grid items in the grid.<br>Default value: **GridItemAlignment.DEFAULT**|
486
487## GridItemAlignment<sup>12+</sup>
488
489Enumerates the alignment modes of grid items.
490
491**Atomic service API**: This API can be used in atomic services since API version 12.
492
493**System capability**: SystemCapability.ArkUI.ArkUI.Full
494
495| Name  | Value| Description                                |
496| ------ |------| -------------------------------------- |
497| DEFAULT  |  0  | Use the default alignment mode of the grid.|
498| STRETCH |  1  | Use the height of the tallest grid item in a row as the height for all other grid items in that row.|
499
500
501> **NOTE**
502>
503> 1. The **STRETCH** option only takes effect in scrollable grids.<br>
504> 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>
505> 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>
506> 4. When **STRETCH** is used, the grid undergoes an additional layout process, which may incur additional performance overhead.
507
508## GridDirection<sup>8+</sup>
509
510Enumerates the main axis layout directions.
511
512**Atomic service API**: This API can be used in atomic services since API version 11.
513
514**System capability**: SystemCapability.ArkUI.ArkUI.Full
515
516| Name  |Value| Description                                |
517| ------ |------| -------------------------------------- |
518| Row  |  0  | Horizontal layout, where the child components are arranged from left to right as the main axis runs along the rows.|
519| Column |  1  | Vertical layout, where the child components are arranged from top to bottom as the main axis runs down the columns.|
520| RowReverse    |  2  | Reverse horizontal layout, where the child components are arranged from right to left as the main axis runs along the rows.|
521| ColumnReverse   |  3  | Reverse vertical layout, where the child components are arranged from bottom up as the main axis runs down the columns.|
522
523> **NOTE**
524>
525> The default value of the universal attribute [clip](ts-universal-attributes-sharp-clipping.md) is **true** for the **Grid** component.
526
527## Events
528
529In addition to [universal events](ts-component-general-events.md) and [scrollable component common events](ts-container-scrollable-common.md#events), the following events are also supported.
530
531### onScrollIndex
532
533onScrollIndex(event: (first: number, last: number) => void)
534
535Triggered 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.
536
537**Atomic service API**: This API can be used in atomic services since API version 11.
538
539**System capability**: SystemCapability.ArkUI.ArkUI.Full
540
541**Parameters**
542
543| Name            | Type  | Mandatory| Description                            |
544| ------------------ | ------ | ---- | -------------------------------- |
545| first              | number | Yes  | Index of the first item of the grid.|
546| last<sup>10+</sup> | number | Yes  | Index of the last item of the grid.|
547
548### onItemDragStart<sup>8+</sup>
549
550onItemDragStart(event: (event: ItemDragInfo, itemIndex: number) => (() => any) \| void)
551
552Triggered when a grid item starts to be dragged. If **void** is returned, the drag operation cannot be performed.
553
554This event is triggered when the user long presses a grid item.
555
556Drag 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.
557
558**Atomic service API**: This API can be used in atomic services since API version 11.
559
560**System capability**: SystemCapability.ArkUI.ArkUI.Full
561
562**Parameters**
563
564| Name   | Type                                 | Mandatory| Description                  |
565| --------- | ------------------------------------- | ---- | ---------------------- |
566| event     | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes  | Information about the drag point.        |
567| itemIndex | number                                | Yes  | Index of the dragged item.|
568
569### onItemDragEnter<sup>8+</sup>
570
571onItemDragEnter(event: (event: ItemDragInfo) => void)
572
573Triggered when the dragged item enters the drop target of the grid.
574
575**Atomic service API**: This API can be used in atomic services since API version 11.
576
577**System capability**: SystemCapability.ArkUI.ArkUI.Full
578
579**Parameters**
580
581| Name| Type                                 | Mandatory| Description          |
582| ------ | ------------------------------------- | ---- | -------------- |
583| event  | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes  | Information about the drag point.|
584
585### onItemDragMove<sup>8+</sup>
586
587onItemDragMove(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number) => void)
588
589Triggered when the dragged item moves over the drop target of the grid.
590
591**Atomic service API**: This API can be used in atomic services since API version 11.
592
593**System capability**: SystemCapability.ArkUI.ArkUI.Full
594
595**Parameters**
596
597| Name     | Type                                 | Mandatory| Description          |
598| ----------- | ------------------------------------- | ---- | -------------- |
599| event       | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes  | Information about the drag point.|
600| itemIndex   | number                                | Yes  | Initial position of the dragged item.|
601| insertIndex | number                                | Yes  | Index of the position to which the dragged item is dropped.|
602
603### onItemDragLeave<sup>8+</sup>
604
605onItemDragLeave(event: (event: ItemDragInfo, itemIndex: number) => void)
606
607Triggered when the dragged item leaves the drop target of the grid.
608
609**Atomic service API**: This API can be used in atomic services since API version 11.
610
611**System capability**: SystemCapability.ArkUI.ArkUI.Full
612
613**Parameters**
614
615| Name   | Type                                 | Mandatory| Description                      |
616| --------- | ------------------------------------- | ---- | -------------------------- |
617| event     | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes  | Information about the drag point.            |
618| itemIndex | number                                | Yes  | Index of the dragged item.|
619
620### onItemDrop<sup>8+</sup>
621
622onItemDrop(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => void)
623
624Triggered when the dragged grid item is dropped on the drop target of the grid.
625
626**isSuccess** returns **true** if the grid item is dropped within the grid, and returns **false** otherwise.
627
628**Atomic service API**: This API can be used in atomic services since API version 11.
629
630**System capability**: SystemCapability.ArkUI.ArkUI.Full
631
632**Parameters**
633
634| Name     | Type                                 | Mandatory| Description          |
635| ----------- | ------------------------------------- | ---- | -------------- |
636| event       | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes  | Information about the drag point.|
637| itemIndex   | number                                | Yes  | Initial position of the dragged item.|
638| insertIndex | number                                | Yes  | Index of the position to which the dragged item is dropped.|
639| isSuccess   | boolean                               | Yes  | Whether the dragged item is successfully dropped.  |
640
641### onScrollBarUpdate<sup>10+</sup>
642
643onScrollBarUpdate(event: (index: number, offset: number) => ComputedBarAttribute)
644
645Triggered at the end of each frame layout in the grid. You can use the callback to set the position and length of the scrollbar.
646
647This API is intended solely for setting the scroll position of the grid. Avoid implementing service logic within this API.
648
649**Atomic service API**: This API can be used in atomic services since API version 11.
650
651**System capability**: SystemCapability.ArkUI.ArkUI.Full
652
653**Parameters**
654
655| Name| Type  | Mandatory| Description                                                        |
656| ------ | ------ | ---- | ------------------------------------------------------------ |
657| index  | number | Yes  | Index of the first item of the grid.                            |
658| offset | number | Yes  | Offset of the displayed first item relative to the start position of the grid, in vp.|
659
660**Return value**
661
662| Type                                                 | Description                |
663| ----------------------------------------------------- | -------------------- |
664| [ComputedBarAttribute](#computedbarattribute10) | Position and length of the scrollbar.|
665
666### onReachStart<sup>10+</sup>
667
668onReachStart(event: () => void)
669
670Triggered when the grid reaches the start position.
671
672This 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.
673
674**Atomic service API**: This API can be used in atomic services since API version 11.
675
676**System capability**: SystemCapability.ArkUI.ArkUI.Full
677
678### onReachEnd<sup>10+</sup>
679
680onReachEnd(event: () => void)
681
682Triggered when the grid reaches the end position.
683
684If 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.
685
686**Atomic service API**: This API can be used in atomic services since API version 11.
687
688**System capability**: SystemCapability.ArkUI.ArkUI.Full
689
690### onScrollFrameBegin<sup>10+</sup>
691
692onScrollFrameBegin(event: (offset: number, state:  ScrollState) => { offsetRemain: number })
693
694Triggered 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.
695
696**Atomic service API**: This API can be used in atomic services since API version 11.
697
698**System capability**: SystemCapability.ArkUI.ArkUI.Full
699
700**Parameters**
701
702| Name| Type                                                   | Mandatory| Description                      |
703| ------ | ------------------------------------------------------- | ---- | -------------------------- |
704| offset | number                                                  | Yes  | Amount to scroll by, in vp.|
705| state  | [ScrollState](ts-container-list.md#scrollstate) | Yes  | Current scroll state.            |
706
707**Return value**
708
709| Type                    | Description                |
710| ------------------------ | -------------------- |
711| { offsetRemain: number } | Actual amount by which the grid scrolls, in vp.|
712
713### onScrollStart<sup>10+</sup>
714
715onScrollStart(event: () => void)
716
717Triggered 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.
718
719**Atomic service API**: This API can be used in atomic services since API version 11.
720
721**System capability**: SystemCapability.ArkUI.ArkUI.Full
722
723### onScrollStop<sup>10+</sup>
724
725onScrollStop(event: () => void)
726
727Triggered 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.
728
729**Atomic service API**: This API can be used in atomic services since API version 11.
730
731**System capability**: SystemCapability.ArkUI.ArkUI.Full
732
733### onScroll<sup>(deprecated)</sup>
734onScroll(event: (scrollOffset: number, scrollState: [ScrollState](ts-container-list.md#scrollstate)) => void)
735
736Triggered when the grid scrolls.
737
738This API is available since API version 10.
739
740This API is deprecated since API version 12. You are advised to use [onDidScroll](ts-container-scrollable-common.md#ondidscroll12) instead.
741
742**Atomic service API**: This API can be used in atomic services since API version 11.
743
744**System capability**: SystemCapability.ArkUI.ArkUI.Full
745
746**Parameters**
747
748| Name| Type| Mandatory| Description|
749| ------ | ------ | ------ | ------|
750| 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|
751| scrollState | [ScrollState](ts-container-list.md#scrollstate) | Yes| Current scroll state.|
752
753## ComputedBarAttribute<sup>10+</sup>
754
755Provides information about the position and length of the scrollbar.
756
757**Atomic service API**: This API can be used in atomic services since API version 11.
758
759**System capability**: SystemCapability.ArkUI.ArkUI.Full
760
761| Name        | Type        | Read Only| Optional|   Description        |
762| ----------- | ------------ | ---- | ---- | ---------- |
763| totalOffset | number | No| No|  Total offset of the grid content relative to the display area, in px.   |
764| totalLength   | number | No| No|  Total length of the grid content, in px.   |
765
766## Example
767
768### Example 1: Creating a Fixed Row and Column Grid Layout
769
770This example demonstrates how to use **onGetRectByIndex** in **GridLayoutOptions** to define the position and size of each grid item.
771
772```ts
773// xxx.ets
774@Entry
775@Component
776struct GridExample {
777  @State numbers1: String[] = ['0', '1', '2', '3', '4']
778  @State numbers2: String[] = ['0', '1','2','3','4','5']
779
780  layoutOptions3: GridLayoutOptions = {
781    regularSize: [1, 1],
782    onGetRectByIndex: (index: number) => {
783      if (index == 0)
784        return [0, 0, 1, 1]
785      else if(index==1)
786        return [0, 1, 2, 2]
787      else if(index==2)
788        return [0 ,3 ,3 ,3]
789      else if(index==3)
790        return [3, 0, 3, 3]
791      else if(index==4)
792        return [4, 3, 2, 2]
793      else
794        return [5, 5, 1, 1]
795    }
796  }
797
798  build() {
799    Column({ space: 5 }) {
800      Grid() {
801        ForEach(this.numbers1, (day: string) => {
802          ForEach(this.numbers1, (day: string) => {
803            GridItem() {
804              Text(day)
805                .fontSize(16)
806                .backgroundColor(0xF9CF93)
807                .width('100%')
808                .height('100%')
809                .textAlign(TextAlign.Center)
810            }
811          }, (day: string) => day)
812        }, (day: string) => day)
813      }
814      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
815      .rowsTemplate('1fr 1fr 1fr 1fr 1fr')
816      .columnsGap(10)
817      .rowsGap(10)
818      .width('90%')
819      .backgroundColor(0xFAEEE0)
820      .height(300)
821
822      Text('Use of GridLayoutOptions: onGetRectByIndex').fontColor(0xCCCCCC).fontSize(9).width('90%')
823
824      Grid(undefined, this.layoutOptions3) {
825        ForEach(this.numbers2, (day: string) => {
826          GridItem() {
827            Text(day)
828              .fontSize(16)
829              .backgroundColor(0xF9CF93)
830              .width('100%')
831              .height("100%")
832              .textAlign(TextAlign.Center)
833          }
834          .height("100%")
835          .width('100%')
836        }, (day: string) => day)
837      }
838      .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
839      .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
840      .columnsGap(10)
841      .rowsGap(10)
842      .width('90%')
843      .backgroundColor(0xFAEEE0)
844      .height(300)
845    }.width('100%').margin({ top: 5 })
846  }
847}
848```
849
850![en-us_image_0000001219744183](figures/en-us_image_0000001219744183.gif)
851
852### Example 2: Implementing a Scrollable Grid with Scroll Events
853
854This example shows a scrollable grid with all its scrolling attributes and events specified.
855
856```ts
857// xxx.ets
858@Entry
859@Component
860struct GridExample {
861  @State numbers: String[] = ['0', '1', '2', '3', '4']
862  scroller: Scroller = new Scroller()
863  @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.
864
865  build() {
866    Column({ space: 5 }) {
867      Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
868      Grid(this.scroller) {
869        ForEach(this.numbers, (day: string) => {
870          ForEach(this.numbers, (day: string) => {
871            GridItem() {
872              Text(day)
873                .fontSize(16)
874                .backgroundColor(0xF9CF93)
875                .width('100%')
876                .height(80)
877                .textAlign(TextAlign.Center)
878            }
879          }, (day: string) => day)
880        }, (day: string) => day)
881      }
882      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
883      .columnsGap(10)
884      .rowsGap(10)
885      .friction(0.6)
886      .enableScrollInteraction(true)
887      .supportAnimation(false)
888      .multiSelectable(false)
889      .edgeEffect(EdgeEffect.Spring)
890      .scrollBar(BarState.On)
891      .scrollBarColor(Color.Grey)
892      .scrollBarWidth(4)
893      .width('90%')
894      .backgroundColor(0xFAEEE0)
895      .height(300)
896      .onScrollIndex((first: number, last: number) => {
897        console.info(first.toString())
898        console.info(last.toString())
899      })
900      .onScrollBarUpdate((index: number, offset: number) => {
901        console.info("XXX" + 'Grid onScrollBarUpdate,index : ' + index.toString() + ",offset" + offset.toString())
902        return { totalOffset: (index / 5) * (80 + 10) - offset, totalLength: 80 * 5 + 10 * 4 }
903      }) // The sample code applies only to the current data source. If the data source changes, modify the code or delete this attribute.
904      .onDidScroll((scrollOffset: number, scrollState: ScrollState) => {
905        console.info(scrollOffset.toString())
906        console.info(scrollState.toString())
907      })
908      .onScrollStart(() => {
909        console.info("XXX" + "Grid onScrollStart")
910      })
911      .onScrollStop(() => {
912        console.info("XXX" + "Grid onScrollStop")
913      })
914      .onReachStart(() => {
915        this.gridPosition = 0
916        console.info("XXX" + "Grid onReachStart")
917      })
918      .onReachEnd(() => {
919        this.gridPosition = 2
920        console.info("XXX" + "Grid onReachEnd")
921      })
922
923      Button('next page')
924        .onClick(() => {// Click to go to the next page.
925          this.scroller.scrollPage({ next: true })
926        })
927    }.width('100%').margin({ top: 5 })
928  }
929}
930```
931
932![scrollerExample2](figures/scrollerExample2.gif)
933
934### Example 3: Implementing a Scrollable Grid with Grid Items Spanning Rows and Columns
935
936This example shows how to use **irregularIndexes** and **onGetIrregularSizeByIndex** in **GridLayoutOptions** to define custom sizes and spans for grid items.
937
938```ts
939// xxx.ets
940@Entry
941@Component
942struct GridExample {
943  @State numbers: String[] = ['0', '1', '2', '3', '4']
944  scroller: Scroller = new Scroller()
945  layoutOptions1: GridLayoutOptions = {
946    regularSize: [1, 1],        // Only [1, 1] is supported.
947    irregularIndexes: [0, 6],   // The grid item whose indexes are 0 and 6 occupies one row.
948  }
949
950  layoutOptions2: GridLayoutOptions = {
951    regularSize: [1, 1],
952    irregularIndexes: [0, 7],   // The number of columns occupied by the grid item whose indexes are 0 and 7 is specified by onGetIrregularSizeByIndex.
953    onGetIrregularSizeByIndex: (index: number) => {
954      if (index === 0) {
955        return [1, 5]
956      }
957      return [1, index % 6 + 1]
958    }
959  }
960
961  build() {
962    Column({ space: 5 }) {
963      Grid(this.scroller, this.layoutOptions1) {
964        ForEach(this.numbers, (day: string) => {
965          ForEach(this.numbers, (day: string) => {
966            GridItem() {
967              Text(day)
968                .fontSize(16)
969                .backgroundColor(0xF9CF93)
970                .width('100%')
971                .height(80)
972                .textAlign(TextAlign.Center)
973            }.selectable(false)
974          }, (day: string) => day)
975        }, (day: string) => day)
976      }
977      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
978      .columnsGap(10)
979      .rowsGap(10)
980      .multiSelectable(true)
981      .scrollBar(BarState.Off)
982      .width('90%')
983      .backgroundColor(0xFAEEE0)
984      .height(300)
985
986      Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
987      // The grid does not scroll, and undefined is used to reserve space.
988      Grid(undefined, this.layoutOptions2) {
989        ForEach(this.numbers, (day: string) => {
990          ForEach(this.numbers, (day: string) => {
991            GridItem() {
992              Text(day)
993                .fontSize(16)
994                .backgroundColor(0xF9CF93)
995                .width('100%')
996                .height(80)
997                .textAlign(TextAlign.Center)
998            }
999          }, (day: string) => day)
1000        }, (day: string) => day)
1001      }
1002      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
1003      .columnsGap(10)
1004      .rowsGap(10)
1005      .scrollBar(BarState.Off)
1006      .width('90%')
1007      .backgroundColor(0xFAEEE0)
1008      .height(300)
1009    }.width('100%').margin({ top: 5 })
1010  }
1011}
1012```
1013
1014![gridLayoutOptions](figures/gridLayoutOptions.gif)
1015
1016### Example 4: Implementing Nested Scrolling in a Grid
1017
1018This example illustrates how to implement nested scrolling in a grid, using **nestedScroll** and **onScrollFrameBegin**:
1019
1020```ts
1021@Entry
1022@Component
1023struct GridExample {
1024  @State colors: number[] = [0xFFC0CB, 0xDA70D6, 0x6B8E23, 0x6A5ACD, 0x00FFFF, 0x00FF7F]
1025  @State numbers: number[] = []
1026  @State translateY: number = 0
1027  private scroller: Scroller = new Scroller()
1028  private gridScroller: Scroller = new Scroller()
1029  private touchDown: boolean = false
1030  private listTouchDown: boolean = false
1031  private scrolling: boolean = false
1032
1033  aboutToAppear() {
1034    for (let i = 0; i < 100; i++) {
1035      this.numbers.push(i)
1036    }
1037  }
1038
1039  build() {
1040    Stack() {
1041      Column() {
1042        Row() {
1043          Text('Head')
1044        }
1045
1046        Column() {
1047          List({ scroller: this.scroller }) {
1048            ListItem() {
1049              Grid() {
1050                GridItem() {
1051                  Text('GoodsTypeList1')
1052                }
1053                .backgroundColor(this.colors[0])
1054                .columnStart(0)
1055                .columnEnd(1)
1056
1057                GridItem() {
1058                  Text('GoodsTypeList2')
1059                }
1060                .backgroundColor(this.colors[1])
1061                .columnStart(0)
1062                .columnEnd(1)
1063
1064                GridItem() {
1065                  Text('GoodsTypeList3')
1066                }
1067                .backgroundColor(this.colors[2])
1068                .columnStart(0)
1069                .columnEnd(1)
1070
1071                GridItem() {
1072                  Text('GoodsTypeList4')
1073                }
1074                .backgroundColor(this.colors[3])
1075                .columnStart(0)
1076                .columnEnd(1)
1077
1078                GridItem() {
1079                  Text('GoodsTypeList5')
1080                }
1081                .backgroundColor(this.colors[4])
1082                .columnStart(0)
1083                .columnEnd(1)
1084              }
1085              .scrollBar(BarState.Off)
1086              .columnsGap(15)
1087              .rowsGap(10)
1088              .rowsTemplate('1fr 1fr 1fr 1fr 1fr')
1089              .columnsTemplate('1fr')
1090              .width('100%')
1091              .height(200)
1092            }
1093
1094            ListItem() {
1095              Grid(this.gridScroller) {
1096                ForEach(this.numbers, (item: number) => {
1097                  GridItem() {
1098                    Text(item + '')
1099                      .fontSize(16)
1100                      .backgroundColor(0xF9CF93)
1101                      .width('100%')
1102                      .height('100%')
1103                      .textAlign(TextAlign.Center)
1104                  }
1105                  .width('100%')
1106                  .height(40)
1107                  .shadow({ radius: 10, color: '#909399', offsetX: 1, offsetY: 1 })
1108                  .borderRadius(10)
1109                  .translate({ x: 0, y: this.translateY })
1110                }, (item: string) => item)
1111              }
1112              .columnsTemplate('1fr 1fr')
1113              .friction(0.3)
1114              .columnsGap(15)
1115              .rowsGap(10)
1116              .scrollBar(BarState.Off)
1117              .width('100%')
1118              .height('100%')
1119              .layoutDirection(GridDirection.Column)
1120              .nestedScroll({
1121                scrollForward: NestedScrollMode.PARENT_FIRST,
1122                scrollBackward: NestedScrollMode.SELF_FIRST
1123              })
1124              .onTouch((event: TouchEvent) => {
1125                if (event.type == TouchType.Down) {
1126                  this.listTouchDown = true
1127                } else if (event.type == TouchType.Up) {
1128                  this.listTouchDown = false
1129                }
1130              })
1131            }
1132          }
1133          .scrollBar(BarState.Off)
1134          .edgeEffect(EdgeEffect.None)
1135          .onTouch((event: TouchEvent) => {
1136            if (event.type == TouchType.Down) {
1137              this.touchDown = true
1138            } else if (event.type == TouchType.Up) {
1139              this.touchDown = false
1140            }
1141          })
1142          .onScrollFrameBegin((offset: number, state: ScrollState) => {
1143            if (this.scrolling && offset > 0) {
1144              let newOffset = this.scroller.currentOffset().yOffset
1145              if (newOffset >= 590) {
1146                this.gridScroller.scrollBy(0, offset)
1147                return { offsetRemain: 0 }
1148              } else if (newOffset + offset > 590) {
1149                this.gridScroller.scrollBy(0, newOffset + offset - 590)
1150                return { offsetRemain: 590 - newOffset }
1151              }
1152            }
1153            return { offsetRemain: offset }
1154          })
1155          .onScrollStart(() => {
1156            if (this.touchDown && !this.listTouchDown) {
1157              this.scrolling = true
1158            }
1159          })
1160          .onScrollStop(() => {
1161            this.scrolling = false
1162          })
1163        }
1164        .width('100%')
1165        .height('100%')
1166        .padding({ left: 10, right: 10 })
1167      }
1168
1169      Row() {
1170        Text('Top')
1171          .width(30)
1172          .height(30)
1173          .borderRadius(50)
1174      }
1175      .padding(5)
1176      .borderRadius(50)
1177      .backgroundColor('#ffffff')
1178      .shadow({ radius: 10, color: '#909399', offsetX: 1, offsetY: 1 })
1179      .margin({ right: 22, bottom: 15 })
1180      .onClick(() => {
1181        this.scroller.scrollTo({ xOffset: 0, yOffset: 0 })
1182        this.gridScroller.scrollTo({ xOffset: 0, yOffset: 0 })
1183      })
1184    }
1185    .align(Alignment.BottomEnd)
1186  }
1187}
1188```
1189
1190![nestedScrollExample4](figures/nestedScrollExample4.gif)
1191
1192### Example 5: Implementing Dragging in a Grid
1193
11941.  Set **editMode\(true\)** to enable edit mode, where the user can drag the grid items.
11952.  In the [onItemDragStart](#onitemdragstart8) callback, set the image to be displayed during dragging.
11963.  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.
1197
1198> **NOTE**
1199>
1200> The drag and drop action is not displayed in the preview.
1201
1202```ts
1203@Entry
1204@Component
1205struct GridExample {
1206  @State numbers: string[] = []
1207  scroller: Scroller = new Scroller()
1208  @State text: string = 'drag'
1209
1210  @Builder pixelMapBuilder () { // Style for the drag event.
1211    Column() {
1212      Text(this.text)
1213        .fontSize(16)
1214        .backgroundColor(0xF9CF93)
1215        .width(80)
1216        .height(80)
1217        .textAlign(TextAlign.Center)
1218    }
1219  }
1220
1221  aboutToAppear() {
1222    for (let i = 1;i <= 15; i++) {
1223      this.numbers.push(i + '')
1224    }
1225  }
1226
1227  changeIndex(index1: number, index2: number) { // Exchange the array position.
1228    let temp: string;
1229    temp = this.numbers[index1];
1230    this.numbers[index1] = this.numbers[index2];
1231    this.numbers[index2] = temp;
1232  }
1233
1234  build() {
1235    Column({ space: 5 }) {
1236      Grid(this.scroller) {
1237        ForEach(this.numbers, (day: string) => {
1238          GridItem() {
1239            Text(day)
1240              .fontSize(16)
1241              .backgroundColor(0xF9CF93)
1242              .width(80)
1243              .height(80)
1244              .textAlign(TextAlign.Center)
1245          }
1246        })
1247      }
1248      .columnsTemplate('1fr 1fr 1fr')
1249      .columnsGap(10)
1250      .rowsGap(10)
1251      .width('90%')
1252      .backgroundColor(0xFAEEE0)
1253      .height(300)
1254      .editMode(true) // Enable edit mode, where the user can drag the grid items.
1255      .onItemDragStart((event: ItemDragInfo, itemIndex: number) => { // Triggered when a grid item starts to be dragged.
1256        this.text = this.numbers[itemIndex]
1257        return this.pixelMapBuilder() // Set the image to be displayed during dragging.
1258      })
1259      .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => { // Triggered when the dragged item is dropped on the drop target of the grid.
1260        // 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.
1261        if (!isSuccess || insertIndex >= this.numbers.length) {
1262          return
1263        }
1264        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.
1265        this.changeIndex(itemIndex, insertIndex)
1266      })
1267    }.width('100%').margin({ top: 5 })
1268  }
1269}
1270```
1271
1272Below are some examples.
1273
1274Below shows how the grid looks when dragging of grid items starts.
1275
1276![gridDrag](figures/gridDrag.png)
1277
1278Below shows how the grid looks when dragging of grid items is in progress.
1279
1280![gridDrag](figures/gridDrag1.png)
1281
1282Below shows how the grid looks after grid item 1 and grid item 6 swap their positions.
1283
1284![gridDrag](figures/gridDrag2.png)
1285
1286### Example 6: Implementing Adaptive Grid Layout
1287
1288This example demonstrates the use of **layoutDirection**, **maxcount**, **minCount**, and **cellLength**:
1289
1290```ts
1291@Entry
1292@Component
1293struct GridExample {
1294  @State numbers: string[] = []
1295
1296  aboutToAppear() {
1297    for (let i = 1; i <= 30; i++) {
1298      this.numbers.push(i + '')
1299    }
1300  }
1301
1302  build() {
1303    Scroll() {
1304      Column({ space: 5 }) {
1305        Blank()
1306        Text('The layoutDirection, maxcount, minCount, and cellLength parameters take effect only when neither rowsTemplate nor columnsTemplate is set.')
1307          .fontSize(15).fontColor(0xCCCCCC).width('90%')
1308        Grid() {
1309          ForEach(this.numbers, (day: string) => {
1310            GridItem() {
1311              Text(day).fontSize(16).backgroundColor(0xF9CF93)
1312            }.width(40).height(80).borderWidth(2).borderColor(Color.Red)
1313          }, (day: string) => day)
1314        }
1315        .height(300)
1316        .columnsGap(10)
1317        .rowsGap(10)
1318        .backgroundColor(0xFAEEE0)
1319        .maxCount(6)
1320        .minCount(2)
1321        .cellLength(0)
1322        .layoutDirection(GridDirection.Row)
1323      }
1324      .width('90%').margin({ top: 5, left: 5, right: 5 })
1325      .align(Alignment.Center)
1326    }
1327  }
1328}
1329```
1330
1331![cellLength](figures/cellLength.gif)
1332
1333### Example 7: Dynamically Adjusting the Number of Grid Columns with a Pinch Gesture
1334
1335This example demonstrates how to adjust the number of columns in the grid with a pinch gesture using two fingers.
1336
1337```ts
1338// xxx.ets
1339@Entry
1340@Component
1341struct GridExample {
1342  @State numbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19']
1343  @State columns: number = 2
1344
1345  aboutToAppear() {
1346    let lastCount = AppStorage.get<number>('columnsCount')
1347    if (typeof lastCount != 'undefined') {
1348      this.columns = lastCount
1349    }
1350  }
1351
1352  build() {
1353    Column({ space: 5 }) {
1354      Row() {
1355        Text('Pinch to change the number of columns')
1356          .height('5%')
1357          .margin({ top: 10, left: 20 })
1358      }
1359
1360      Grid() {
1361        ForEach(this.numbers, (day: string) => {
1362          ForEach(this.numbers, (day: string) => {
1363            GridItem() {
1364              Text(day)
1365                .fontSize(16)
1366                .backgroundColor(0xF9CF93)
1367                .width('100%')
1368                .height(80)
1369                .textAlign(TextAlign.Center)
1370            }
1371          }, (day: string) => day)
1372        }, (day: string) => day)
1373      }
1374      .columnsTemplate('1fr '.repeat(this.columns))
1375      .columnsGap(10)
1376      .rowsGap(10)
1377      .width('90%')
1378      .scrollBar(BarState.Off)
1379      .backgroundColor(0xFAEEE0)
1380      .height('100%')
1381      .cachedCount(3)
1382      // Switching the number of columns triggers a reordering animation for the item positions.
1383      .animation({
1384        duration: 300,
1385        curve: Curve.Smooth
1386      })
1387      .priorityGesture(
1388        PinchGesture()
1389          .onActionEnd((event: GestureEvent) => {
1390            console.info('end scale:' + event.scale)
1391            // 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.
1392            if (event.scale > 2) {
1393              this.columns--
1394            } else if (event.scale < 0.6) {
1395              this.columns++
1396            }
1397            // 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.
1398            this.columns = Math.min(4, Math.max(1, this.columns));
1399            AppStorage.setOrCreate<number>('columnsCount', this.columns)
1400          })
1401      )
1402    }.width('100%').margin({ top: 5 })
1403  }
1404}
1405```
1406
1407![pinch](figures/grid-pinch.gif)
1408
1409### Example 8: Using Adaptive Column Count Settings
1410This example shows the usage of **auto-fill**, **auto-fit**, and **auto-stretch** in [columnsTemplate](#columnstemplate).
1411
1412```ts
1413@Entry
1414@Component
1415struct GridColumnsTemplate {
1416  data: number[] = [0, 1, 2, 3, 4, 5]
1417  data1: number[] = [0, 1, 2, 3, 4, 5]
1418  data2: number[] = [0, 1, 2, 3, 4, 5]
1419
1420  build() {
1421    Column({ space: 10 }) {
1422      Text('auto-fill auto-calculates the number of columns based on the set column width').width('90%')
1423      Grid() {
1424        ForEach(this.data, (item: number) => {
1425          GridItem() {
1426            Text('N' + item).height(80)
1427          }
1428          .backgroundColor(Color.Orange)
1429        })
1430      }
1431      .width('90%')
1432      .border({ width: 1, color: Color.Black })
1433      .columnsTemplate('repeat(auto-fill, 70)')
1434      .columnsGap(10)
1435      .rowsGap(10)
1436      .height(150)
1437
1438      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%')
1439      Grid() {
1440        ForEach(this.data1, (item: number) => {
1441          GridItem() {
1442            Text('N' + item).height(80)
1443          }
1444          .backgroundColor(Color.Orange)
1445        })
1446      }
1447      .width('90%')
1448      .border({ width: 1, color: Color.Black })
1449      .columnsTemplate('repeat(auto-fit, 70)')
1450      .columnsGap(10)
1451      .rowsGap(10)
1452      .height(150)
1453
1454      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%')
1455      Grid() {
1456        ForEach(this.data2, (item: number) => {
1457          GridItem() {
1458            Text('N' + item).height(80)
1459          }
1460          .backgroundColor(Color.Orange)
1461        })
1462      }
1463      .width('90%')
1464      .border({ width: 1, color: Color.Black })
1465      .columnsTemplate('repeat(auto-stretch, 70)')
1466      .columnsGap(10)
1467      .rowsGap(10)
1468      .height(150)
1469    }
1470    .width('100%')
1471    .height('100%')
1472  }
1473}
1474```
1475
1476![gridColumnsTemplate](figures/gridColumnsTemplate.png)
1477
1478### Example 9: Setting Grid Item Heights Based on the Tallest Item in the Current Row
1479This 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.
1480
1481By default, the heights of the left and right grid items may differ; however, after the grid's [alignItems](#alignitems12) 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.
1482
1483```ts
1484@Entry
1485@Component
1486struct Index {
1487  @State data: number[] = [];
1488  @State items: number[] = [];
1489
1490  aboutToAppear(): void {
1491    for (let i = 0; i < 100; i++) {
1492      this.data.push(i)
1493      this.items.push(this.getSize())
1494    }
1495  }
1496
1497  getSize() {
1498    let ret = Math.floor(Math.random() * 5)
1499    return Math.max(1, ret)
1500  }
1501
1502  build() {
1503    Column({ space: 10 }) {
1504      Text('Grid alignItems sample code')
1505
1506      Grid() {
1507        ForEach(this.data, (item: number) => {
1508          // 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.
1509          // 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.
1510          GridItem() {
1511            Column() {
1512              Column().height(100).backgroundColor('#D5D5D5').width('100%')
1513              // The Text component in the center is set with flexGrow(1) to automatically fill the available space within the parent component.
1514              Text('This is a piece of text.'.repeat(this.items[item]))
1515                .flexGrow(1).width('100%').align(Alignment.TopStart)
1516                .backgroundColor('#F7F7F7')
1517              Column().height(50).backgroundColor('#707070').width('100%')
1518            }
1519          }
1520          .border({ color: Color.Black, width: 1 })
1521        })
1522      }
1523      .columnsGap(10)
1524      .rowsGap(5)
1525      .columnsTemplate('1fr 1fr')
1526      .width('80%')
1527      .height('100%')
1528      // 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.
1529      .alignItems(GridItemAlignment.STRETCH)
1530      .scrollBar(BarState.Off)
1531    }
1532    .height('100%')
1533    .width('100%')
1534  }
1535}
1536
1537```
1538![gridAlignItems](figures/gridAlignItems.png)
1539
1540### Example 10: Setting Edge Fading
1541This example demonstrates how to enable the edge fading effect using [fadingEdge](ts-container-scrollable-common.md#fadingedge14).
1542
1543```ts
1544// xxx.ets
1545// This example demonstrates how to implement a Grid component with an edge fading effect and set the length of the fading edge.
1546import { LengthMetrics } from '@kit.ArkUI'
1547@Entry
1548@Component
1549struct GridExample {
1550  @State numbers: String[] = ['0', '1', '2', '3', '4']
1551  @State rowNumbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
1552  scroller: Scroller = new Scroller()
1553
1554  build() {
1555    Column({ space: 5 }) {
1556      Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
1557      Grid(this.scroller) {
1558        ForEach(this.rowNumbers, (day: string) => {
1559          ForEach(this.numbers, (day: string) => {
1560            GridItem() {
1561              Text(day)
1562                .fontSize(16)
1563                .backgroundColor(0xF9CF93)
1564                .width('100%')
1565                .height(80)
1566                .textAlign(TextAlign.Center)
1567            }
1568          }, (day: string) => day)
1569        }, (day: string) => day)
1570      }
1571      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
1572      .columnsGap(10)
1573      .rowsGap(20)
1574      .height('90%')
1575      .fadingEdge(true,{fadingEdgeLength:LengthMetrics.vp(80)})
1576
1577    }.width('100%').margin({ top: 5 })
1578  }
1579}
1580```
1581
1582![fadingEdge_grid](figures/fadingEdge_grid.gif)
1583
1584### Example 11: Setting the Single-Side Edge Effect
1585
1586This example demonstrates how to set a single-side edge effect for the **Grid** component using the **edgeEffect** API.
1587
1588```ts
1589// xxx.ets
1590@Entry
1591@Component
1592struct GridExample {
1593  @State numbers: String[] = ['0', '1', '2', '3', '4']
1594  @State rowNumbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
1595  scroller: Scroller = new Scroller()
1596
1597  build() {
1598    Column({ space: 5 }) {
1599      Grid(this.scroller) {
1600        ForEach(this.rowNumbers, (day: string) => {
1601          ForEach(this.numbers, (day: string) => {
1602            GridItem() {
1603              Text(day)
1604                .fontSize(16)
1605                .backgroundColor(0xF9CF93)
1606                .width('100%')
1607                .height(80)
1608                .textAlign(TextAlign.Center)
1609            }
1610          }, (day: string) => day)
1611        }, (day: string) => day)
1612      }
1613      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
1614      .columnsGap(10)
1615      .rowsGap(20)
1616      .edgeEffect(EdgeEffect.Spring,{alwaysEnabled:true,effectEdge:EffectEdge.START})
1617      .width('90%')
1618      .backgroundColor(0xDCDCDC)
1619      .height('80%')
1620
1621    }.width('100%').margin({ top: 5 })
1622  }
1623}
1624```
1625
1626![edgeEffect_grid](figures/edgeEffect_grid.gif)
1627