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