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