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