# Grid
The **Grid** component consists of cells formed by rows and columns. You can specify the cells where items are located to form various layouts.
> **NOTE**
>
> This component is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version.
## Child Components
Only 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.
> **NOTE**
>
> Below are the rules for calculating the indexes of the child components of **Grid**:
>
> The index increases in ascending order of child components.
>
> In the **if/else** statement, only the child components in the branch where the condition is met participate in the index calculation.
>
> In the **ForEach**, **LazyForEach**, or **Repeat** statement, the indexes of all expanded child nodes are calculated.
>
> 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.
>
> The child component that has the **visibility** attribute set to **Hidden** or **None** is included in the index calculation.
>
> The child component that has the **visibility** attribute set to **None** is not displayed, but still takes up the corresponding cell.
>
> 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.
>
> 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.
## APIs
Grid(scroller?: Scroller, layoutOptions?: GridLayoutOptions)
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------------------------- | ---- | ------------------------------------------------------------ |
| scroller | [Scroller](ts-container-scroll.md#scroller) | No | Controller, which can be bound to scrollable components.
**NOTE**
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).|
| layoutOptions10+ | [GridLayoutOptions](#gridlayoutoptions10) | No| Grid layout options.|
## GridLayoutOptions10+
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
Defines 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.
| Name | Type | Mandatory | Description |
| ----- | ------- | ---- | --------------------- |
| 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.
**Atomic service API**: This API can be used in atomic services since API version 11. |
| 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.
**Atomic service API**: This API can be used in atomic services since API version 11.|
| 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.
**Atomic service API**: This API can be used in atomic services since API version 11.|
| onGetRectByIndex11+ | (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],
where **rowStart** indicates the row start position, **columnStart** indicates the column start position,
**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.
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.
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.
**NOTE**
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].
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.
**Atomic service API**: This API can be used in atomic services since API version 12.|
## Attributes
In 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.
### columnsTemplate
columnsTemplate(value: string)
Sets 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.
For 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.
**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**.
**columnsTemplate('repeat(auto-fill, track-size)')**: The layout automatically calculates the number of columns based on the fixed column width specified with **track-size**.
**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**.
**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.
In **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.
For visual reference, see [Example 8](#example-8).
If 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------ | ---- | ---------------------------------- |
| value | string | Yes | Number of columns or minimum column width of the grid.|
### rowsTemplate
rowsTemplate(value: string)
Sets 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.
For 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.
**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**.
**rowsTemplate('repeat(auto-fill, track-size)')**: The layout automatically calculates the number of rows based on the fixed row height specified with **track-size**.
**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**.
**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.
In **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.
If 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------ | ---- | ---------------------------------- |
| value | string | Yes | Number of rows or minimum row height of the grid.|
> **NOTE**
>
> Depending on the settings of the **rowsTemplate** and **columnsTemplate** attributes, the **Grid** component supports the following layout modes:
>
> 1. **rowsTemplate** and **columnsTemplate** are both set
>
> - The **Grid** component displays only elements in a fixed number of rows and columns and cannot be scrolled.
> - In this mode, the following attributes do not take effect: **layoutDirection**, **maxCount**, **minCount**, and **cellLength**.
> - If the width and height of a grid are not set, the grid adapts to the size of its parent component by default.
> - 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.
> - By default, the grid items fill the entire grid.
>
> 2. Either **rowsTemplate** or **columnsTemplate** is set
>
> - The **Grid** component arranges elements in the specified direction and allows for scrolling to display excess elements.
> - If **columnsTemplate** is set, the component scrolls vertically, the main axis runs vertically, and the cross axis runs horizontally.
> - If **rowsTemplate** is set, the component scrolls horizontally, the main axis runs horizontally, and the cross axis runs vertically.
> - In this mode, the following attributes do not take effect: **layoutDirection**, **maxCount**, **minCount**, and **cellLength**.
> - 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.
> - 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.
>
> 3. Neither **rowsTemplate** nor **columnsTemplate** is set
>
> - 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**.
> - 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.
> - In this mode, only the following attributes take effect: **layoutDirection**, **maxCount**, **minCount**, **cellLength**, **editMode**, **columnsGap**, and **rowsGap**.
> - 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.
> - 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.
> - If there are no grid items in the grid, the width and height of the grid are set to 0.
>
### columnsGap
columnsGap(value: Length)
Sets the gap between columns. A value less than 0 evaluates to the default value.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ---------------------------- | ---- | ---------------------------- |
| value | [Length](ts-types.md#length) | Yes | Gap between columns.
Default value: **0**|
### rowsGap
rowsGap(value: Length)
Sets the gap between rows. A value less than 0 evaluates to the default value.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ---------------------------- | ---- | ---------------------------- |
| value | [Length](ts-types.md#length) | Yes | Gap between rows.
Default value: **0**|
### scrollBar
scrollBar(value: BarState)
Sets the scrollbar state.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ----------------------------------------- | ---- | ------------------------------------------------------------ |
| value | [BarState](ts-appendix-enums.md#barstate) | Yes | Scrollbar state.
Default value: **BarState.Auto**
**NOTE**
In API version 9 and earlier versions, the default value is **BarState.Off**. Since API version 10, the default value is **BarState.Auto**.|
### scrollBarColor
scrollBarColor(value: Color | number | string)
Sets the scrollbar color.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------------------------------------------------------------ | ---- | -------------- |
| value | [Color](ts-appendix-enums.md#color) \| number \| string | Yes | Scrollbar color.
Default value: **'\#182431'** (40% opacity)|
### scrollBarWidth
scrollBarWidth(value: number | string)
Sets 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | -------------------------- | ---- | ----------------------------------------- |
| value | number \| string | Yes | Scrollbar width.
Default value: **4**
Unit: vp|
### cachedCount
cachedCount(value: number)
Sets 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. For details, see [Minimizing White Blocks During Swiping](../../../performance/arkts-performance-improvement-recommendation.md#minimizing-white-blocks-during-swiping).
The 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.
In [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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------ | ---- | -------------------------------------- |
| value | number | Yes | Number of grid items to be cached (preloaded).
Default value: **1**|
### cachedCount14+
cachedCount(count: number, show: boolean)
Sets the number of grid items to be cached (preloaded) and specifies whether to display the preloaded nodes.
The 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.
**Atomic service API**: This API can be used in atomic services since API version 14.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------ | ---- | -------------------------------------- |
| count | number | Yes | Number of grid items to be preloaded.
Default value: **1**|
| show | boolean | Yes | Whether to display the preloaded nodes.
Default value: **false**|
### editMode8+
editMode(value: boolean)
Sets whether to enable edit mode. In edit mode, the user can drag the [grid items](ts-container-griditem.md) in the **Grid** component.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------ | ---- | ---------------------------------------- |
| value | boolean | Yes | Whether to enable edit mode.
Default value: **false**|
### layoutDirection8+
layoutDirection(value: GridDirection)
Sets the main axis direction of the grid.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ---------------------------------------- | ---- | ---------------------------------------------- |
| value | [GridDirection](#griddirection8) | Yes | Main axis direction of the grid.
Default value: **GridDirection.Row**|
### maxCount8+
maxCount(value: number)
Sets the maximum number of rows or columns that can be displayed. A value less than 1 evaluates to the default value.
When **layoutDirection** is **Row** or **RowReverse**, the value indicates the maximum number of columns that can be displayed.
When **layoutDirection** is **Column** or **ColumnReverse**, the value indicates the maximum number of rows that can be displayed.
If the value of **maxCount** is smaller than that of **minCount**, the default values of **maxCount** and **minCount** are used.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------ | ---- | --------------------------------------------- |
| value | number | Yes | Maximum number of rows or columns that can be displayed.
Default value: **Infinity**|
### minCount8+
minCount(value: number)
Sets the minimum number of rows or columns that can be displayed. A value less than 1 evaluates to the default value.
When **layoutDirection** is **Row** or **RowReverse**, the value indicates the minimum number of columns that can be displayed.
When **layoutDirection** is **Column** or **ColumnReverse**, the value indicates the minimum number of rows that can be displayed.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------ | ---- | -------------------------------------- |
| value | number | Yes | Minimum number of rows or columns that can be displayed.
Default value: **1**|
### cellLength8+
cellLength(value: number)
Sets the height per row or width per column.
When **layoutDirection** is **Row** or **RowReverse**, the value indicates the height per row.
When **layoutDirection** is **Column** or **ColumnReverse**, the value indicates the width per column.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------ | ---- | ------------------------------------------------------- |
| value | number | Yes | Height per row or width per column.
Default value: size of the first element
Unit: vp|
### multiSelectable8+
multiSelectable(value: boolean)
Sets 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).
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------- | ---- | ------------------------------------------------------------ |
| value | boolean | Yes | Whether to enable multiselect.
Default value: **false**
**false**: Multiselect is disabled. **true**: Multiselect is disabled.|
### supportAnimation8+
supportAnimation(value: boolean)
Sets 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).
Drag animations are only supported in grids with fixed size rules; scenarios involving spanning across rows or columns are not supported.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------- | ---- | -------------------------------- |
| value | boolean | Yes | Whether to enable animation.
Default value: **false**|
### edgeEffect10+
edgeEffect(value: EdgeEffect, options?: EdgeEffectOptions)
Sets the effect used when the scroll boundary is reached.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name | Type | Mandatory| Description |
| --------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
| value | [EdgeEffect](ts-appendix-enums.md#edgeeffect) | Yes | Effect used when the scroll boundary is reached. The spring and shadow effects are supported.
Default value: **EdgeEffect.None**|
| options11+ | [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.
Default value: **{ alwaysEnabled: false }**|
### enableScrollInteraction10+
enableScrollInteraction(value: boolean)
Sets 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------- | ---- | ----------------------------------- |
| value | boolean | Yes | Whether to support scroll gestures.
Default value: **true**|
### nestedScroll10+
nestedScroll(value: NestedScrollOptions)
Sets 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------------------------------------------------------------ | ---- | -------------- |
| value | [NestedScrollOptions](ts-container-scrollable-common.md#nestedscrolloptions10) | Yes | Nested scrolling options.|
### friction10+
friction(value: number | Resource)
Sets 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ---------------------------------------------------- | ---- | ----------------------------------------------------------- |
| value | number \| [Resource](ts-types.md#resource) | Yes | Friction coefficient.
Default value: **0.9** for wearable devices and **0.6** for non-wearable devices
Since API version 11, the default value for non-wearable devices is **0.7**.
Since API version 12, the default value for non-wearable devices is **0.75**.|
### alignItems12+
alignItems(alignment: Optional\)
Sets the alignment mode of grid items in the grid. For details, see [Example 9](#example-9).
**Atomic service API**: This API can be used in atomic services since API version 12.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name | Type | Mandatory| Description |
| ---------- | ------ | ---- | ------------------------------- |
| alignment | Optional\<[GridItemAlignment](#griditemalignment12)\> | Yes | Alignment mode of grid items in the grid.
Default value: **GridItemAlignment.DEFAULT**|
## GridItemAlignment12+
**Atomic service API**: This API can be used in atomic services since API version 12.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
| Name | Value| Description |
| ------ |------| -------------------------------------- |
| DEFAULT | 0 | Use the default alignment mode of the grid.|
| STRETCH | 1 | Use the height of the tallest grid item in a row as the height for all other grid items in that row.|
> **NOTE**
>
> 1. The **STRETCH** option only takes effect in scrollable grids.
> 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.
> 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.
> 4. When **STRETCH** is used, the grid undergoes an additional layout process, which may incur additional performance overhead.
## GridDirection8+
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
| Name |Value| Description |
| ------ |------| -------------------------------------- |
| Row | 0 | Horizontal layout, where the child components are arranged from left to right as the main axis runs along the rows.|
| Column | 1 | Vertical layout, where the child components are arranged from top to bottom as the main axis runs down the columns.|
| RowReverse | 2 | Reverse horizontal layout, where the child components are arranged from right to left as the main axis runs along the rows.|
| ColumnReverse | 3 | Reverse vertical layout, where the child components are arranged from bottom up as the main axis runs down the columns.|
> **NOTE**
>
> The default value of the universal attribute [clip](ts-universal-attributes-sharp-clipping.md) is **true** for the **Grid** component.
## Events
In 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.
### onScrollIndex
onScrollIndex(event: (first: number, last: number) => void)
Triggered 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name | Type | Mandatory| Description |
| ------------------ | ------ | ---- | -------------------------------- |
| first | number | Yes | Index of the first item of the grid.|
| last10+ | number | Yes | Index of the last item of the grid.|
### onItemDragStart8+
onItemDragStart(event: (event: ItemDragInfo, itemIndex: number) => (() => any) \| void)
Triggered when a grid item starts to be dragged. If **void** is returned, the drag operation cannot be performed.
This event is triggered when the user long presses a grid item.
Drag 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name | Type | Mandatory| Description |
| --------- | ------------------------------------- | ---- | ---------------------- |
| event | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes | Information about the drag point. |
| itemIndex | number | Yes | Index of the dragged item.|
### onItemDragEnter8+
onItemDragEnter(event: (event: ItemDragInfo) => void)
Triggered when the dragged item enters the drop target of the grid.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------------------------------------- | ---- | -------------- |
| event | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes | Information about the drag point.|
### onItemDragMove8+
onItemDragMove(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number) => void)
Triggered when the dragged item moves over the drop target of the grid.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name | Type | Mandatory| Description |
| ----------- | ------------------------------------- | ---- | -------------- |
| event | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes | Information about the drag point.|
| itemIndex | number | Yes | Initial position of the dragged item.|
| insertIndex | number | Yes | Index of the position to which the dragged item is dropped.|
### onItemDragLeave8+
onItemDragLeave(event: (event: ItemDragInfo, itemIndex: number) => void)
Triggered when the dragged item leaves the drop target of the grid.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name | Type | Mandatory| Description |
| --------- | ------------------------------------- | ---- | -------------------------- |
| event | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes | Information about the drag point. |
| itemIndex | number | Yes | Index of the dragged item.|
### onItemDrop8+
onItemDrop(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => void)
Triggered when the dragged item is dropped on the drop target of the grid.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name | Type | Mandatory| Description |
| ----------- | ------------------------------------- | ---- | -------------- |
| event | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo) | Yes | Information about the drag point.|
| itemIndex | number | Yes | Initial position of the dragged item.|
| insertIndex | number | Yes | Index of the position to which the dragged item is dropped.|
| isSuccess | boolean | Yes | Whether the dragged item is successfully dropped. |
### onScrollBarUpdate10+
onScrollBarUpdate(event: (index: number, offset: number) => ComputedBarAttribute)
Triggered when the first item displayed in the grid changes. You can use the callback to set the position and length of the scrollbar.
This API is intended solely for setting the scroll position of the grid. Avoid implementing service logic within this API.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------ | ---- | ------------------------------------------------------------ |
| index | number | Yes | Index of the first item of the grid. |
| offset | number | Yes | Offset of the displayed first item relative to the start position of the grid, in vp.|
**Return value**
| Type | Description |
| ----------------------------------------------------- | -------------------- |
| [ComputedBarAttribute](#computedbarattribute10) | Position and length of the scrollbar.|
### onReachStart10+
onReachStart(event: () => void)
Triggered when the grid reaches the start position.
This 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
### onReachEnd10+
onReachEnd(event: () => void)
Triggered when the grid reaches the end position.
If 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
### onScrollFrameBegin10+
onScrollFrameBegin(event: (offset: number, state: ScrollState) => { offsetRemain: number })
Triggered 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type | Mandatory| Description |
| ------ | ------------------------------------------------------- | ---- | -------------------------- |
| offset | number | Yes | Amount to scroll by, in vp.|
| state | [ScrollState](ts-container-list.md#scrollstate) | Yes | Current scroll state. |
**Return value**
| Type | Description |
| ------------------------ | -------------------- |
| { offsetRemain: number } | Actual amount by which the grid scrolls, in vp.|
### onScrollStart10+
onScrollStart(event: () => void)
Triggered 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
### onScrollStop10+
onScrollStop(event: () => void)
Triggered 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
### onScroll(deprecated)
onScroll(event: (scrollOffset: number, scrollState: [ScrollState](ts-container-list.md#scrollstate)) => void)
Triggered when the grid scrolls.
This 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.
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
**Parameters**
| Name| Type| Mandatory| Description|
| ------ | ------ | ------ | ------|
| 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.
Unit: vp|
| scrollState | [ScrollState](ts-container-list.md#scrollstate) | Yes| Current scroll state.|
## ComputedBarAttribute10+
**Atomic service API**: This API can be used in atomic services since API version 11.
**System capability**: SystemCapability.ArkUI.ArkUI.Full
| Name | Type | Read Only| Optional| Description |
| ----------- | ------------ | ---- | ---- | ---------- |
| totalOffset | number | No| No| Total offset of the grid content relative to the display area, in px. |
| totalLength | number | No| No| Total length of the grid content, in px. |
## Example
### Example 1
This 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.
```ts
// xxx.ets
@Entry
@Component
struct GridExample {
@State numbers1: String[] = ['0', '1', '2', '3', '4']
@State numbers2: String[] = ['0', '1','2','3','4','5']
layoutOptions3: GridLayoutOptions = {
regularSize: [1, 1],
onGetRectByIndex: (index: number) => {
if (index == 0)
return [0, 0, 1, 1]
else if(index==1)
return [0, 1, 2, 2]
else if(index==2)
return [0 ,3 ,3 ,3]
else if(index==3)
return [3, 0, 3, 3]
else if(index==4)
return [4, 3, 2, 2]
else
return [5, 5, 1, 1]
}
}
build() {
Column({ space: 5 }) {
Grid() {
ForEach(this.numbers1, (day: string) => {
ForEach(this.numbers1, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
}, (day: string) => day)
}, (day: string) => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
Text('Use of GridLayoutOptions: onGetRectByIndex').fontColor(0xCCCCCC).fontSize(9).width('90%')
Grid(undefined, this.layoutOptions3) {
ForEach(this.numbers2, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height("100%")
.textAlign(TextAlign.Center)
}
.height("100%")
.width('100%')
}, (day: string) => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
}.width('100%').margin({ top: 5 })
}
}
```

### Example 2
This example shows a scrollable grid with all its scrolling attributes and events specified.
```ts
// xxx.ets
@Entry
@Component
struct GridExample {
@State numbers: String[] = ['0', '1', '2', '3', '4']
scroller: Scroller = new Scroller()
@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.
build() {
Column({ space: 5 }) {
Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
Grid(this.scroller) {
ForEach(this.numbers, (day: string) => {
ForEach(this.numbers, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height(80)
.textAlign(TextAlign.Center)
}
}, (day: string) => day)
}, (day: string) => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.friction(0.6)
.enableScrollInteraction(true)
.supportAnimation(false)
.multiSelectable(false)
.edgeEffect(EdgeEffect.Spring)
.scrollBar(BarState.On)
.scrollBarColor(Color.Grey)
.scrollBarWidth(4)
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
.onScrollIndex((first: number, last: number) => {
console.info(first.toString())
console.info(last.toString())
})
.onScrollBarUpdate((index: number, offset: number) => {
console.info("XXX" + 'Grid onScrollBarUpdate,index : ' + index.toString() + ",offset" + offset.toString())
return { totalOffset: (index / 5) * (80 + 10) - offset, totalLength: 80 * 5 + 10 * 4 }
}) // The sample code applies only to the current data source. If the data source changes, modify the code or delete this attribute.
.onDidScroll((scrollOffset: number, scrollState: ScrollState) => {
console.info(scrollOffset.toString())
console.info(scrollState.toString())
})
.onScrollStart(() => {
console.info("XXX" + "Grid onScrollStart")
})
.onScrollStop(() => {
console.info("XXX" + "Grid onScrollStop")
})
.onReachStart(() => {
this.gridPosition = 0
console.info("XXX" + "Grid onReachStart")
})
.onReachEnd(() => {
this.gridPosition = 2
console.info("XXX" + "Grid onReachEnd")
})
Button('next page')
.onClick(() => {// Click to go to the next page.
this.scroller.scrollPage({ next: true })
})
}.width('100%').margin({ top: 5 })
}
}
```

### Example 3
This example uses **irregularIndexes** and **onGetIrregularSizeByIndex** in **GridLayoutOptions**.
```ts
// xxx.ets
@Entry
@Component
struct GridExample {
@State numbers: String[] = ['0', '1', '2', '3', '4']
scroller: Scroller = new Scroller()
layoutOptions1: GridLayoutOptions = {
regularSize: [1, 1], // Only [1, 1] is supported.
irregularIndexes: [0, 6], // The grid item whose indexes are 0 and 6 occupies one row.
}
layoutOptions2: GridLayoutOptions = {
regularSize: [1, 1],
irregularIndexes: [0, 7], // The number of columns occupied by the grid item whose indexes are 0 and 7 is specified by onGetIrregularSizeByIndex.
onGetIrregularSizeByIndex: (index: number) => {
if (index === 0) {
return [1, 5]
}
return [1, index % 6 + 1]
}
}
build() {
Column({ space: 5 }) {
Grid(this.scroller, this.layoutOptions1) {
ForEach(this.numbers, (day: string) => {
ForEach(this.numbers, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height(80)
.textAlign(TextAlign.Center)
}.selectable(false)
}, (day: string) => day)
}, (day: string) => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.multiSelectable(true)
.scrollBar(BarState.Off)
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
// The grid does not scroll, and undefined is used to reserve space.
Grid(undefined, this.layoutOptions2) {
ForEach(this.numbers, (day: string) => {
ForEach(this.numbers, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height(80)
.textAlign(TextAlign.Center)
}
}, (day: string) => day)
}, (day: string) => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.scrollBar(BarState.Off)
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
}.width('100%').margin({ top: 5 })
}
}
```

### Example 4
Example of using **nestedScroll** and **onScrollFrameBegin**:
```ts
@Entry
@Component
struct GridExample {
@State colors: number[] = [0xFFC0CB, 0xDA70D6, 0x6B8E23, 0x6A5ACD, 0x00FFFF, 0x00FF7F]
@State numbers: number[] = []
@State translateY: number = 0
private scroller: Scroller = new Scroller()
private gridScroller: Scroller = new Scroller()
private touchDown: boolean = false
private listTouchDown: boolean = false
private scrolling: boolean = false
aboutToAppear() {
for (let i = 0; i < 100; i++) {
this.numbers.push(i)
}
}
build() {
Stack() {
Column() {
Row() {
Text('Head')
}
Column() {
List({ scroller: this.scroller }) {
ListItem() {
Grid() {
GridItem() {
Text('GoodsTypeList1')
}
.backgroundColor(this.colors[0])
.columnStart(0)
.columnEnd(1)
GridItem() {
Text('GoodsTypeList2')
}
.backgroundColor(this.colors[1])
.columnStart(0)
.columnEnd(1)
GridItem() {
Text('GoodsTypeList3')
}
.backgroundColor(this.colors[2])
.columnStart(0)
.columnEnd(1)
GridItem() {
Text('GoodsTypeList4')
}
.backgroundColor(this.colors[3])
.columnStart(0)
.columnEnd(1)
GridItem() {
Text('GoodsTypeList5')
}
.backgroundColor(this.colors[4])
.columnStart(0)
.columnEnd(1)
}
.scrollBar(BarState.Off)
.columnsGap(15)
.rowsGap(10)
.rowsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsTemplate('1fr')
.width('100%')
.height(200)
}
ListItem() {
Grid(this.gridScroller) {
ForEach(this.numbers, (item: number) => {
GridItem() {
Text(item + '')
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
.width('100%')
.height(40)
.shadow({ radius: 10, color: '#909399', offsetX: 1, offsetY: 1 })
.borderRadius(10)
.translate({ x: 0, y: this.translateY })
}, (item: string) => item)
}
.columnsTemplate('1fr 1fr')
.friction(0.3)
.columnsGap(15)
.rowsGap(10)
.scrollBar(BarState.Off)
.width('100%')
.height('100%')
.layoutDirection(GridDirection.Column)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
.onTouch((event: TouchEvent) => {
if (event.type == TouchType.Down) {
this.listTouchDown = true
} else if (event.type == TouchType.Up) {
this.listTouchDown = false
}
})
}
}
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None)
.onTouch((event: TouchEvent) => {
if (event.type == TouchType.Down) {
this.touchDown = true
} else if (event.type == TouchType.Up) {
this.touchDown = false
}
})
.onScrollFrameBegin((offset: number, state: ScrollState) => {
if (this.scrolling && offset > 0) {
let newOffset = this.scroller.currentOffset().yOffset
if (newOffset >= 590) {
this.gridScroller.scrollBy(0, offset)
return { offsetRemain: 0 }
} else if (newOffset + offset > 590) {
this.gridScroller.scrollBy(0, newOffset + offset - 590)
return { offsetRemain: 590 - newOffset }
}
}
return { offsetRemain: offset }
})
.onScrollStart(() => {
if (this.touchDown && !this.listTouchDown) {
this.scrolling = true
}
})
.onScrollStop(() => {
this.scrolling = false
})
}
.width('100%')
.height('100%')
.padding({ left: 10, right: 10 })
}
Row() {
Text('Top')
.width(30)
.height(30)
.borderRadius(50)
}
.padding(5)
.borderRadius(50)
.backgroundColor('#ffffff')
.shadow({ radius: 10, color: '#909399', offsetX: 1, offsetY: 1 })
.margin({ right: 22, bottom: 15 })
.onClick(() => {
this.scroller.scrollTo({ xOffset: 0, yOffset: 0 })
this.gridScroller.scrollTo({ xOffset: 0, yOffset: 0 })
})
}
.align(Alignment.BottomEnd)
}
}
```

### Example 5
1. Set **editMode\(true\)** to enable edit mode, where the user can drag the grid items.
2. In the [onItemDragStart](#onitemdragstart8) callback, set the image to be displayed during dragging.
3. 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.
> **NOTE**
>
> The drag and drop action is not displayed in the preview.
```ts
@Entry
@Component
struct GridExample {
@State numbers: string[] = []
scroller: Scroller = new Scroller()
@State text: string = 'drag'
@Builder pixelMapBuilder () { // Style for the drag event.
Column() {
Text(this.text)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width(80)
.height(80)
.textAlign(TextAlign.Center)
}
}
aboutToAppear() {
for (let i = 1;i <= 15; i++) {
this.numbers.push(i + '')
}
}
changeIndex(index1: number, index2: number) { // Exchange the array position.
let temp: string;
temp = this.numbers[index1];
this.numbers[index1] = this.numbers[index2];
this.numbers[index2] = temp;
}
build() {
Column({ space: 5 }) {
Grid(this.scroller) {
ForEach(this.numbers, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width(80)
.height(80)
.textAlign(TextAlign.Center)
}
})
}
.columnsTemplate('1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
.editMode(true) // Enable edit mode, where the user can drag the grid items.
.onItemDragStart((event: ItemDragInfo, itemIndex: number) => { // Triggered when a grid item starts to be dragged.
this.text = this.numbers[itemIndex]
return this.pixelMapBuilder() // Set the image to be displayed during dragging.
})
.onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => { // Triggered when the dragged item is dropped on the drop target of the grid.
// 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.
if (!isSuccess || insertIndex >= this.numbers.length) {
return
}
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.
this.changeIndex(itemIndex, insertIndex)
})
}.width('100%').margin({ top: 5 })
}
}
```
Below are some examples.
Below shows how the grid looks when dragging of grid items starts.

Below shows how the grid looks when dragging of grid items is in progress.

Below shows how the grid looks after grid item 1 and grid item 6 swap their positions.

### Example 6
Example of using **layoutDirection**, **maxcount**, **minCount**, and **cellLength**:
```ts
@Entry
@Component
struct GridExample {
@State numbers: string[] = []
aboutToAppear() {
for (let i = 1; i <= 30; i++) {
this.numbers.push(i + '')
}
}
build() {
Scroll() {
Column({ space: 5 }) {
Blank()
Text('The layoutDirection, maxcount, minCount, and cellLength parameters take effect only when neither rowsTemplate nor columnsTemplate is set.')
.fontSize(15).fontColor(0xCCCCCC).width('90%')
Grid() {
ForEach(this.numbers, (day: string) => {
GridItem() {
Text(day).fontSize(16).backgroundColor(0xF9CF93)
}.width(40).height(80).borderWidth(2).borderColor(Color.Red)
}, (day: string) => day)
}
.height(300)
.columnsGap(10)
.rowsGap(10)
.backgroundColor(0xFAEEE0)
.maxCount(6)
.minCount(2)
.cellLength(0)
.layoutDirection(GridDirection.Row)
}
.width('90%').margin({ top: 5, left: 5, right: 5 })
.align(Alignment.Center)
}
}
}
```

### Example 7
This example demonstrates how to adjust the number of columns in the grid with a pinch gesture using two fingers.
```ts
// xxx.ets
@Entry
@Component
struct GridExample {
@State numbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19']
@State columns: number = 2
aboutToAppear() {
let lastCount = AppStorage.get('columnsCount')
if (typeof lastCount != 'undefined') {
this.columns = lastCount
}
}
build() {
Column({ space: 5 }) {
Row() {
Text('Pinch to change the number of columns')
.height('5%')
.margin({ top: 10, left: 20 })
}
Grid() {
ForEach(this.numbers, (day: string) => {
ForEach(this.numbers, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height(80)
.textAlign(TextAlign.Center)
}
}, (day: string) => day)
}, (day: string) => day)
}
.columnsTemplate('1fr '.repeat(this.columns))
.columnsGap(10)
.rowsGap(10)
.width('90%')
.scrollBar(BarState.Off)
.backgroundColor(0xFAEEE0)
.height('100%')
.cachedCount(3)
// Switching the number of columns triggers a reordering animation for the item positions.
.animation({
duration: 300,
curve: Curve.Smooth
})
.priorityGesture(
PinchGesture()
.onActionEnd((event: GestureEvent) => {
console.info('end scale:' + event.scale)
// 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.
if (event.scale > 2) {
this.columns--
} else if (event.scale < 0.6) {
this.columns++
}
// 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.
this.columns = Math.min(4, Math.max(1, this.columns));
AppStorage.setOrCreate('columnsCount', this.columns)
})
)
}.width('100%').margin({ top: 5 })
}
}
```

### Example 8
This example shows the usage of **auto-fill**, **auto-fit**, and **auto-stretch** in the [columnsTemplate](#columnstemplate) attribute.
```ts
@Entry
@Component
struct GridColumnsTemplate {
data: number[] = [0, 1, 2, 3, 4, 5]
data1: number[] = [0, 1, 2, 3, 4, 5]
data2: number[] = [0, 1, 2, 3, 4, 5]
build() {
Column({ space: 10 }) {
Text('auto-fill auto-calculates the number of columns based on the set column width').width('90%')
Grid() {
ForEach(this.data, (item: number) => {
GridItem() {
Text('N' + item).height(80)
}
.backgroundColor(Color.Orange)
})
}
.width('90%')
.border({ width: 1, color: Color.Black })
.columnsTemplate('repeat(auto-fill, 70)')
.columnsGap(10)
.rowsGap(10)
.height(150)
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%')
Grid() {
ForEach(this.data1, (item: number) => {
GridItem() {
Text('N' + item).height(80)
}
.backgroundColor(Color.Orange)
})
}
.width('90%')
.border({ width: 1, color: Color.Black })
.columnsTemplate('repeat(auto-fit, 70)')
.columnsGap(10)
.rowsGap(10)
.height(150)
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%')
Grid() {
ForEach(this.data2, (item: number) => {
GridItem() {
Text('N' + item).height(80)
}
.backgroundColor(Color.Orange)
})
}
.width('90%')
.border({ width: 1, color: Color.Black })
.columnsTemplate('repeat(auto-stretch, 70)')
.columnsGap(10)
.rowsGap(10)
.height(150)
}
.width('100%')
.height('100%')
}
}
```

### Example 9
This 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.
By 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.
```ts
@Entry
@Component
struct Index {
@State data: number[] = [];
@State items: number[] = [];
aboutToAppear(): void {
for (let i = 0; i < 100; i++) {
this.data.push(i)
this.items.push(this.getSize())
}
}
getSize() {
let ret = Math.floor(Math.random() * 5)
return Math.max(1, ret)
}
build() {
Column({ space: 10 }) {
Text('Grid alignItems sample code')
Grid() {
ForEach(this.data, (item: number) => {
// 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.
// 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.
GridItem() {
Column() {
Column().height(100).backgroundColor('#D5D5D5').width('100%')
// The Text component in the center is set with flexGrow(1) to automatically fill the available space within the parent component.
Text('This is a piece of text.'.repeat(this.items[item]))
.flexGrow(1).width('100%').align(Alignment.TopStart)
.backgroundColor('#F7F7F7')
Column().height(50).backgroundColor('#707070').width('100%')
}
}
.border({ color: Color.Black, width: 1 })
})
}
.columnsGap(10)
.rowsGap(5)
.columnsTemplate('1fr 1fr')
.width('80%')
.height('100%')
// 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.
.alignItems(GridItemAlignment.STRETCH)
.scrollBar(BarState.Off)
}
.height('100%')
.width('100%')
}
}
```

### Example 10
```ts
// xxx.ets
// This example demonstrates how to implement a Grid component with an edge fading effect and set the length of the fading edge.
import { LengthMetrics } from '@kit.ArkUI'
@Entry
@Component
struct GridExample {
@State numbers: String[] = ['0', '1', '2', '3', '4']
@State rowNumbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
scroller: Scroller = new Scroller()
build() {
Column({ space: 5 }) {
Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
Grid(this.scroller) {
ForEach(this.rowNumbers, (day: string) => {
ForEach(this.numbers, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height(80)
.textAlign(TextAlign.Center)
}
}, (day: string) => day)
}, (day: string) => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(20)
.height('90%')
.fadingEdge(true,{fadingEdgeLength:LengthMetrics.vp(80)})
}.width('100%').margin({ top: 5 })
}
}
```
