| value | string | No | Text input in the search text box.<br>Since API version 10, this parameter supports two-way binding through [$$](../../quick-start/arkts-two-way-sync.md).|
| icon | string | No | Path to the search icon. By default, the system search icon is used.<br>For details about the supported image types, see [Image](ts-basic-components-image.md).|
| controller | SearchController | No | Controller of the **\<Search>** component. |
@@ -9,7 +9,23 @@ The **\<Grid>** component consists of cells formed by rows and columns. You can
## Child Components
This component contains the child component **[\<GridItem>](ts-container-griditem.md)**.
The **\<Grid>** component accepts only **\<[GridItem](ts-container-griditem.md)>** as its child components.
> **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** or **LazyForEach** statement, the indexes of all expanded subnodes are calculated.
>
> If the values of [if/else](../../quick-start/arkts-rendering-control-ifelse.md), [ForEach](../../quick-start/arkts-rendering-control-foreach.md), and [LazyForEach](../../quick-start/arkts-rendering-control-lazyforeach.md) change, the indexes of subnodes are updated.
>
> Child components of **\<Grid>** whose **visibility** attribute is set to **Hidden** or **None** are included in the index calculation.
>
> Child components of **\<Grid>** whose **visibility** attribute is set to **None** are not displayed, but still take up the corresponding cells.
## APIs
...
...
@@ -17,9 +33,10 @@ This component contains the child component **[\<GridItem>](ts-container-gridite
| 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](ts-container-list.md).|
## Attributes
...
...
@@ -27,41 +44,57 @@ In addition to the [universal attributes](ts-universal-attributes-size.md), the
| Name| Type| Description|
| -------- | -------- | -------- |
| columnsTemplate | string | Number of columns in the current grid layout. If this attribute is not set, one column is used by default.<br>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.|
| rowsTemplate | string | Number of rows in the current grid layout. If this attribute is not set, one row is used by default.<br>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.|
| columnsGap | Length | Gap between columns.<br>Default value: **0**|
| rowsGap | Length | Gap between rows.<br>Default value: **0**|
| scrollBarColor | string \| number \|Color | Color of the scrollbar.|
| scrollBarWidth | string \| number | Width of the scrollbar.|
| cachedCount | number | Number of grid items to be preloaded. For details, see [Minimizing White Blocks During Swiping](../../ui/ui-ts-performance-improvement-recommendation.md#minimizing-white-blocks-during-swiping).<br>Default value: **1**|
| editMode <sup>8+</sup> | boolean | Whether to enter editing mode. In editing mode, the user can drag the **[\<GridItem>](ts-container-griditem.md)** in the **\<Grid>** component.<br>Default value: **false**|
| columnsTemplate | string | Number of columns in the current grid layout. If this attribute is not set, one column is used by default.<br>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.<br>**NOTE**<br>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.|
| rowsTemplate | string | Number of rows in the current grid layout. If this attribute is not set, one row is used by default.<br>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.<br>**NOTE**<br>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.|
| columnsGap | [Length](ts-types.md#length) | Gap between columns.<br>Default value: **0**<br>**NOTE**<br>A value less than 0 evaluates to the default value.|
| rowsGap | [Length](ts-types.md#length) | Gap between rows.<br>Default value: **0**<br>**NOTE**<br>A value less than 0 evaluates to the default value.|
| scrollBarColor | string \| number \|[Color](ts-appendix-enums.md#color) | Color of the scrollbar.|
| scrollBarWidth | string \| number | Width of the scrollbar. After the width is set, the scrollbar is displayed with the set width in normal state and pressed state.<br>Default value: **4**<br>Unit: vp|
| cachedCount | number | Number of grid items to be preloaded (cached). It works only in [LazyForEach](../../quick-start/arkts-rendering-control-lazyforeach.md). For details, see [Minimizing White Blocks During Swiping](../../ui/arkts-performance-improvement-recommendation.md#minimizing-white-blocks-during-swiping).<br>Default value: **1**<br>**NOTE**<br>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.<br>Grid items that exceed the display and cache range are released.<br>A value less than 0 evaluates to the default value.|
| editMode <sup>8+</sup> | boolean | Whether to enter editing mode. In editing mode, the user can drag the **\<[GridItem](ts-container-griditem.md)>** in the **\<Grid>** component.<br>Default value: **false**|
| layoutDirection<sup>8+</sup> | [GridDirection](#griddirection8) | Main axis direction of the grid.<br>Default value: **GridDirection.Row**|
| maxCount<sup>8+</sup> | number | When **layoutDirection** is **Row** or **RowReverse**: maximum number of columns that can be displayed.<br>When **layoutDirection** is **Column** or **ColumnReverse**: maximum number of rows that can be displayed.<br>Default value: **Infinity**|
| minCount<sup>8+</sup> | number | When **layoutDirection** is **Row** or **RowReverse**: minimum number of columns that can be displayed.<br>When **layoutDirection** is **Column** or **ColumnReverse**: maximum number of rows that can be displayed.<br>Default value: **1**|
| maxCount<sup>8+</sup> | number | When **layoutDirection** is **Row** or **RowReverse**: maximum number of columns that can be displayed.<br>When **layoutDirection** is **Column** or **ColumnReverse**: maximum number of rows that can be displayed.<br>Default value: **Infinity**<br>**NOTE**<br>If the value of **maxCount** is smaller than that of **minCount**, the default values of **maxCount** and **minCount** are used.<br>A value less than 0 evaluates to the default value.|
| minCount<sup>8+</sup> | number | When **layoutDirection** is **Row** or **RowReverse**: minimum number of columns that can be displayed.<br>When **layoutDirection** is **Column** or **ColumnReverse**: minimum number of rows that can be displayed.<br>Default value: **1**<br>**NOTE**<br>A value less than 0 evaluates to the default value.|
| cellLength<sup>8+</sup> | number | When **layoutDirection** is **Row** or **RowReverse**: fixed height per row.<br>When **layoutDirection** is **Column** or **ColumnReverse**: fixed width per column.<br>Default value: size of the first element|
| multiSelectable<sup>8+</sup> | boolean | Whether to enable mouse frame selection.<br>Default value: **false**<br>- **false**: The mouse frame selection is disabled.<br>- **true**: The mouse frame selection is enabled.|
| supportAnimation<sup>8+</sup> | boolean | Whether to enable animation. Currently, the grid item drag animation is supported.<br>Default value: **false**|
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>** displays only elements in a fixed number of rows and columns and cannot be scrolled. For example, if both **rowsTemplate** and **columnsTemplate** are set to **"1fr 1fr"**, only four elements (two rows and two columns) are displayed.
In this mode, the following attributes do not take effect: **layoutDirection**, **maxCount**, minCount, and **cellLength**.
- 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.
- In this mode, if a grid item has both **rowStart** and **columnStart** set, it is placed in the position based on the settings. If a grid item already exists in this position, overlapping occurs.
- If a grid item has only **rowStart** or **columnStart** set, the system traverses the previous grid item layout to search for an idle position that meets the settings. If no idle position meets the requirements, the grid item is not laid out.
- If a grid item has neither **rowStart** nor **columnStart** set, the system traverses the previous grid item layout to search for an idle position. If no idle position is available, the grid item is not laid out.
- If a grid item has **rowEnd** set but not **rowStart**, **rowStart** is considered as set to the same value as **rowEnd**. If a grid item has **columnEnd** set but not **columnStart**, **columnStart** is considered as set to the same value as **columnEnd**.
2. Either **rowsTemplate** or **columnsTemplate** is set
The **\<Grid>** arranges elements in the specified direction and allows for scrolling to display excess elements. For example, if the **\<Grid>** has 10 elements and **columnsTemplate** is set to **"1fr 1fr 1fr"**, it contains three columns. The elements are arranged in the same direction as the main axis runs down the columns. Elements outside the **\<Grid>** area can be viewed through scrolling.
In this mode, the following attributes do not take effect: **layoutDirection**, **maxCount**, **minCount**, and **cellLength**.
- 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 height of all grid items in the cross axis direction of the current grid.
- In this mode, if a grid item has both **rowStart** and **columnStart** set, it is placed in the position based on the settings. If a grid item already exists in this position, overlapping occurs.
- If a grid item has only **rowStart** or **columnStart** set, the system traverses the previous grid item layout to search for an idle position that meets the settings.
- If a grid item has neither **rowStart** nor **columnStart** set, the system traverses the previous grid item layout to search for an idle position.
- If a grid item has **rowEnd** set but not **rowStart**, **rowStart** is considered as set to the same value as **rowEnd**. If a grid item has **columnEnd** set but not **columnStart**, **columnStart** is considered as set to the same value as **columnEnd**.
3. Neither **rowsTemplate** nor **columnsTemplate** is set
The **\<Grid>** 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**.
- 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**, elements 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 top of the content is centered.
- When **layoutDirection** is set to **Column**, elements are arranged from top to bottom. When a column is full, a new column will be added. If the remaining height is insufficient, no more elements will be laid out, and the top of the content is centered.
- In this mode, **rowStart** and **columnStart** of the grid item do not take effect.
## GridDirection<sup>8+</sup>
...
...
@@ -72,14 +105,18 @@ Depending on the settings of the **rowsTemplate** and **columnsTemplate** attrib
| RowReverse | Reverse horizontal layout, where the child components are arranged from right to left as the main axis runs along the rows.|
| ColumnReverse | 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 the [universal events](ts-universal-events-click.md), the following events are supported.
| Name| Description|
| -------- | -------- |
| onScrollIndex(event: (first: number) => void) | Triggered when the start item of the grid changes.<br>- **first**: index of the start item of the grid.|
| onItemDragStart(event: (event: ItemDragInfo, itemIndex: number) => (() => any) \| void) | Triggered when a grid item starts to be dragged.<br>- **event**: See [ItemDragInfo](#itemdraginfo).<br>- **itemIndex**: index of the dragged element.|
| onScrollIndex(event: (first: number) => void) | Triggered when the start item of the grid changes. It is triggered once when the grid is initialized.<br>- **first**: index of the start item of the grid.<br>If it changes, this event will be triggered.|
| onItemDragStart(event: (event: ItemDragInfo, itemIndex: number) => (() => any) \| void) | Triggered when a grid item starts to be dragged.<br>- **event**: See [ItemDragInfo](#itemdraginfo).<br>- **itemIndex**: index of the dragged element.<br>**NOTE**<br>If **void** is returned, the drag operation cannot be performed.<br>This event is triggered when the user long presses a grid item.|
| onItemDragEnter(event: (event: ItemDragInfo) => void) | Triggered when the dragged item enters the drop target of the grid.<br>- **event**: See [ItemDragInfo](#itemdraginfo).|
| onItemDragMove(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number) => void) | Triggered when the dragged item moves over the drop target of the grid.<br>- **event**: See [ItemDragInfo](#itemdraginfo).<br>- **itemIndex**: initial position of the dragged item.<br>- **insertIndex**: index of the position to which the dragged item will be dropped.|
| onItemDragLeave(event: (event: ItemDragInfo, itemIndex: number) => void) | Triggered when the dragged item exits the drop target of the grid.<br>- **event**: See [ItemDragInfo](#itemdraginfo).<br>- **itemIndex**: index of the dragged item.|
...
...
@@ -89,8 +126,8 @@ In addition to the [universal events](ts-universal-events-click.md), the followi
| Name | Type | Description |
| ---------- | ---------- | ---------- |
| x | number | X-coordinate of the dragged item. |
| y | number | Y-coordinate of the dragged item. |
@@ -12,6 +12,24 @@ The **\<List>** component provides a list container that presents a series of li
This component supports the **[\<ListItem>](ts-container-listitem.md)** and **[\<ListItemGroup>](ts-container-listitemgroup.md)** child components.
> **NOTE**
>
> Below are the rules for calculating the indexes of the child components of **\<List>**:
>
> 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** or **LazyForEach** statement, the indexes of all expanded subnodes are calculated.
>
> If the values of [if/else](../../quick-start/arkts-rendering-control-ifelse.md), [ForEach](../../quick-start/arkts-rendering-control-foreach.md), and [LazyForEach](../../quick-start/arkts-rendering-control-lazyforeach.md) change, the indexes of subnodes are updated.
>
> Each **\<ListItemGroup>** component is taken as a whole and assigned an index, and the indexes of the list items within are not included in the index calculation.
>
> Child components of **\<List>** whose **visibility** attribute is set to **Hidden** or **None** are included in the index calculation.
>
> Child components of **\<List>** whose **visibility** attribute is set to **None** are not displayed, but the spacing above and below them still takes effect.
## APIs
...
...
@@ -23,9 +41,9 @@ Since API version 9, this API is supported in ArkTS widgets.
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| space | number \| string | No| Spacing between list items.<br>Default value: **0**|
| initialIndex | number | No| Item displayed at the beginning of the viewport when the current list is loaded for the first time, that is, the first item to be displayed. If the value set is greater than the sequence number of the last item, the setting does not take effect.<br>Default value: **0**|
| scroller | [Scroller](ts-container-scroll.md#scroller) | No| Scroller, which can be bound to scrollable components.|
| space | number \| string | No| Spacing between list items along the main axis.<br>Default value: **0**<br>**NOTE**<br>If this parameter is set to a percentage or a negative number other than -1, the default value is used.<br>If the value of **space** is less than the width of the list divider, the latter is used as the spacing.|
| initialIndex | number | No| Item displayed at the beginning of the viewport when the current list is loaded for the first time, that is, the first item to be displayed.<br>Default value: **0**<br>**NOTE**<br>If this parameter is set to a negative value other than -1 or is greater than the index value of the last item in the current list, the value is invalid. In this case, the default value is used.|
| scroller | [Scroller](ts-container-scroll.md#scroller) | No| Scroller, which can be bound to scrollable components.<br>**NOTE**<br>The scroller cannot be bound to other scrollable components. |
## Attributes
...
...
@@ -34,16 +52,16 @@ In addition to the [universal attributes](ts-universal-attributes-size.md), the
| Name| Type| Description|
| -------- | -------- | -------- |
| listDirection | [Axis](ts-appendix-enums.md#axis) | Direction in which the list items are arranged.<br>Default value: **Axis.Vertical**<br>Since API version 9, this API is supported in ArkTS widgets.|
| divider | {<br>strokeWidth: [Length](ts-types.md#length),<br>color?:[ResourceColor](ts-types.md#resourcecolor),<br>startMargin?: Length,<br>endMargin?: Length<br>} \| null | Style of the divider for the list items. By default, there is no divider.<br>- **strokeWidth**: stroke width of the divider.<br>- **color**: color of the divider.<br>- **startMargin**: distance between the divider and the start edge of the list.<br>- **endMargin**: distance between the divider and the end edge of the list.<br>Since API version 9, this API is supported in ArkTS widgets.|
| scrollBar | [BarState](ts-appendix-enums.md#barstate) | Scrollbar status.<br>Default value: **BarState.Off**<br>Since API version 9, this API is supported in ArkTS widgets.|
| cachedCount | number | Number of list items or list item groups to be preloaded. A list item group is calculated as a whole, and all list items of the group are preloaded at the same time. For details, see [Minimizing White Blocks During Swiping](../../ui/ui-ts-performance-improvement-recommendation.md#minimizing-white-blocks-during-swiping).<br>Default value: **1**<br>Since API version 9, this API is supported in ArkTS widgets.|
| editMode | boolean | Whether to enter editing mode.<br>Default value: **false**|
| edgeEffect | [EdgeEffect](ts-appendix-enums.md#edgeeffect) | Scroll effect.<br>Default value: **EdgeEffect.Spring**<br>Since API version 9, this API is supported in ArkTS widgets.|
| divider | {<br>strokeWidth: [Length](ts-types.md#length),<br>color?:[ResourceColor](ts-types.md#resourcecolor),<br>startMargin?: Length,<br>endMargin?: Length<br>} \| null | Style of the divider for the list items. By default, there is no divider. This attribute cannot be set in percentage.<br>- **strokeWidth**: stroke width of the divider.<br>- **color**: color of the divider.<br>- **startMargin**: distance between the divider and the start edge of the list.<br>- **endMargin**: distance between the divider and the end edge of the list.<br>Since API version 9, this API is supported in ArkTS widgets.<br>The sum of **endMargin** and **startMargin** cannot exceed the column width.<br>**startMargin** and **endMargin** cannot be set in percentage.<br>The divider is drawn between list items along the main axis, and not above the first list item and below the last list item.<br>In multi-column mode, the value of **startMargin** is calculated from the start edge of the cross axis of each column. In other cases, it is calculated from the start edge of the cross axis of the list.|
| scrollBar | [BarState](ts-appendix-enums.md#barstate) | Scrollbar status.<br>Default value: **BarState.Off**<br>Since API version 9, this API is supported in ArkTS widgets.<br>**NOTE**<br>In API version 9 and earlier versions, the default value is **BarState.Off**. In API version 10, the default value is **BarState.Auto**.|
| cachedCount | number | Number of list items or list item groups to be preloaded (cached). It works only in [LazyForEach](../../quick-start/arkts-rendering-control-lazyforeach.md). A list item group is calculated as a whole, and all list items of the group are preloaded at the same time. For details, see [Minimizing White Blocks During Swiping](../../ui/arkts-performance-improvement-recommendation.md#minimizing-white-blocks-during-swiping).<br>Default value: **1**<br>Since API version 9, this API is supported in ArkTS widgets.<br>**NOTE**<br>In single-column mode, the number of the list items to be cached before and after the currently displayed one equals the value of **cachedCount**.<br>In multi-column mode, the number of the list items to be cached is the value of **cachedCount** multiplied by the number of columns.|
| editMode<sup>(deprecated)</sup> | boolean | Whether to enter editing mode.<br>This API is deprecated since API version 9.<br>Default value: **false**|
| edgeEffect | [EdgeEffect](ts-appendix-enums.md#edgeeffect) | Scroll effect. The spring effect and shadow effect are supported.<br>Default value: **EdgeEffect.Spring**<br>Since API version 9, this API is supported in ArkTS widgets.|
| chainAnimation | boolean | Whether to display chained animations on this list when it slides or its top or bottom is dragged. The list items are separated with even space, and one item animation starts after the previous animation during basic sliding interactions. The chained animation effect is similar with spring physics.<br>Default value: **false**<br>- **false**: No chained animations are displayed.<br>- **true**: Chained animations are displayed.<br>Since API version 9, this API is supported in ArkTS widgets.|
| multiSelectable<sup>8+</sup> | boolean | Whether to enable mouse frame selection.<br>Default value: **false**<br>- **false**: The mouse frame selection is disabled.<br>- **true**: The mouse frame selection is enabled.<br>Since API version 9, this API is supported in ArkTS widgets.|
| lanes<sup>9+</sup> | number \|[LengthConstrain](ts-types.md#lengthconstrain) | In the following description, **listDirection** is set to **Axis.Vertical**:<br>Number of columns in which the list items are arranged along the cross axis.<br>Default value: **1**<br>The rules are as follows:<br>- If the value is set to a number, the column width is determined based on the specified number and the cross-axis width of the **\<List>** component.<br>- If the value is set to {minLength, maxLength}, the number of columns is adjusted adaptively based on the width of the **\<List>** component, ensuring that the width respects the {minLength, maxLength} constraints during adaptation. The **minLength** constraint is prioritized. For example, if **lanes** is set to **{minLength: 40vp, maxLength: 60vp}** and the width of the **\<List>** component is 70 vp, the list items are arranged in one column with their alignment compliant with the **alignListItem** settings. If the width of the **\<List>** component is changed to 80 vp, which is twice the value of **minLength**, the list items are arranged in two columns.<br>This API is supported in ArkTS widgets.|
| alignListItem<sup>9+</sup> | ListItemAlign | Alignment mode of list items along the cross axis when: Cross-axis width of the **\<List>** component > Cross-axis width of list items x Value of **lanes**.<br>Default value: **ListItemAlign.Start**<br>This API is supported in ArkTS widgets.|
| sticky<sup>9+</sup> | StickyStyle | Whether to pin the header to the top or the footer to the bottom in the **\<ListItemGroup>** component. This attribute is used together with the **[\<ListItemGroup>](ts-container-listitemgroup.md)** component.<br>Default value: **StickyStyle.None**<br>This API is supported in ArkTS widgets.<br>**NOTE**<br>The **sticky** attribute can be set to **StickyStyle.Header** or \|**StickyStyle.Footer** to support both the pin-to-top and pin-to-bottom features.|
| lanes<sup>9+</sup> | number \|[LengthConstrain](ts-types.md#lengthconstrain) | In the following description, **listDirection** is set to **Axis.Vertical**:<br>Number of columns in which the list items are arranged along the cross axis.<br>Default value: **1**<br>The rules are as follows:<br>- If the value is set to a number, the column width is calculated by dividing the cross-axis width of the **\<List>** component by the specified number.<br>- If the value is set to {minLength, maxLength}, the number of columns is adjusted adaptively based on the width of the **\<List>** component, ensuring that the width respects the {minLength, maxLength} constraints during adaptation. The **minLength** constraint is prioritized.<br>- If the value is set to {minLength, maxLength}, and the cross-axis width constraint of the parent component is infinite, the parent component is arranged by column, and the column width is calculated based on the maximum width of list items in the display area.<br>- Each list item group occupies one row in multi-column mode. Its child list items are arranged based on the **lanes** attribute of the list.<br>- If the value is set to {minLength, maxLength}, the number of columns is calculated based on the cross-axis width of the list item group. If the cross-axis width of the list item group is different from that of the list, the number of columns in the list item group may be different from that in the list.<br>This API is supported in ArkTS widgets. |
| alignListItem<sup>9+</sup> | [ListItemAlign](#listitemalign9) | Alignment mode of list items along the cross axis when: Cross-axis width of the **\<List>** component > Cross-axis width of list items x Value of **lanes**.<br>Default value: **ListItemAlign.Start**<br>This API is supported in ArkTS widgets.|
| sticky<sup>9+</sup> | [StickyStyle](#stickystyle9) | Whether to pin the header to the top or the footer to the bottom in the **\<ListItemGroup>** component. This attribute is used together with the **[\<ListItemGroup>](ts-container-listitemgroup.md)** component.<br>Default value: **StickyStyle.None**<br>This API is supported in ArkTS widgets.<br>**NOTE**<br>The **sticky** attribute can be set to **StickyStyle.Header** or \|**StickyStyle.Footer** to support both the pin-to-top and pin-to-bottom features.|
## ListItemAlign<sup>9+</sup>
...
...
@@ -62,21 +80,23 @@ This API is supported in ArkTS widgets.
| None | In the **\<ListItemGroup>** component, the header is not pinned to the top, and the footer is not pinned to the bottom.|
| Header | In the **\<ListItemGroup>** component, the header is pinned to the top.|
| Footer | In the **\<ListItemGroup>** component, the footer is pinned to the bottom.|
| Header | In the **\<ListItemGroup>** component, the header is pinned to the top, and the footer is not pinned to the bottom.|
| Footer | In the **\<ListItemGroup>** component, the footer is pinned to the bottom, and the header is not pinned to the top.|
> **NOTE**
>
> The default value of the universal attribute [clip](ts-universal-attributes-sharp-clipping.md) is **true** for the **\<List>** component.
## Events
| Name| Description|
| -------- | -------- |
| onItemDelete(event: (index: number) => boolean) | Triggered when a list item is deleted.<br>- **index**: index of the deleted list item. |
| onScroll(event: (scrollOffset: number, scrollState: ScrollState) => void) | Triggered when the list scrolls.<br>- **scrollOffset**: scroll offset.<br>- **[scrollState](#scrollstate)**: current scroll state.<br>Since API version 9, this API is supported in ArkTS widgets.|
| onScrollIndex(event: (start: number, end: number) => void) | Triggered when scrolling starts.<br>When calculating the index value, the **\<ListItemGroup>** accounts for one index value as a whole, and the index values of the list items within are not calculated.<br>- **start**: index of the scroll start position.<br>- **end**: index of the scroll end position.<br>Since API version 9, this API is supported in ArkTS widgets.|
| onReachStart(event: () => void) | Triggered when the list reaches the start position.<br>Since API version 9, this API is supported in ArkTS widgets.|
| onReachEnd(event: () => void) | Triggered when the list reaches the end position.<br>Since API version 9, this API is supported in ArkTS widgets.|
| onScrollFrameBegin<sup>9+</sup>(event: (offset: number, state: ScrollState) => { offsetRemain }) | Triggered when the list starts to scroll. The input parameters indicate the amount by which the list will scroll. The event handler then works out the amount by which the list needs to scroll based on the real-world situation and returns the result.<br>\-**offset**: amount to scroll by.<br>\-**state**: current sliding status.<br>- **offsetRemain**: actual amount by which the list scrolls.<br>This API is supported in ArkTS widgets.|
| onItemDelete<sup>(deprecated)</sup>(event: (index: number) => boolean) | Triggered when a list item is deleted.<br>This API is deprecated since API version 9.<br>- **index**: index of the deleted list item.|
| onScroll(event: (scrollOffset: number, scrollState: ScrollState) => void) | Triggered when the list scrolls.<br>- **scrollOffset**: scroll offset of each frame. The offset is positive when the list is scrolled up and negative when the list is scrolled down.<br>- **[scrollState](#scrollstate)**: current scroll state.<br>This event is not triggered when **ScrollEdge** and **ScrollToIndex** are called by using the controller. In other cases, this event is triggered when scrolling occurs.<br>Since API version 9, this API is supported in ArkTS widgets.|
| onScrollIndex(event: (start: number, end: number) => void) | Triggered when a child component enters or exits from the list display area.<br>During index calculation, each **\<ListItemGroup>** component is taken as a whole and assigned an index, and the indexes of the list items within are not included in the calculation.<br>- **start**: index of the scroll start position.<br>- **end**: index of the scroll end position.<br>This event is triggered once when the list is initialized and when the index of the first list item or the next list item in the list display area changes.<br>When the list edge effect is the spring effect, the **onScrollIndex** event is not triggered when the user scrolls the list to the edge or releases the list to rebound.<br>Since API version 9, this API is supported in ArkTS widgets.|
| onReachStart(event: () => void) | Triggered when the list reaches the start position.<br>Since API version 9, this API is supported in ArkTS widgets.<br>**NOTE**<br>This event is triggered once when **initialIndex** is **0** during list initialization and once when the list scrolls to the start position. When the list edge effect is the spring effect, this event is triggered once when the list passes the start position and is triggered again when the list returns to the start position.|
| onReachEnd(event: () => void) | Triggered when the list reaches the end position.<br>Since API version 9, this API is supported in ArkTS widgets.<br>**NOTE**<br>When the list edge effect is the spring effect, this event is triggered once when the list passes the end position and is triggered again when the list returns to the end position.|
| onScrollFrameBegin<sup>9+</sup>(event: (offset: number, state: ScrollState) => { offsetRemain }) | Triggered when the list starts to scroll. The input parameters indicate the amount by which the list will scroll. The event handler then works out the amount by which the list needs to scroll based on the real-world situation and returns the result.<br>\-**offset**: amount to scroll by, in vp.<br>\-**state**: current sliding status.<br>- **offsetRemain**: actual amount by which the list scrolls, in vp.<br>This event is triggered when the user starts dragging the list or the list starts inertial scrolling. This event is not triggered when the list rebounds or the scrolling controller is used.<br>This API is supported in ArkTS widgets.<br>**NOTE**<br>If **listDirection** is set to **Axis.Vertical**, the return value is the amount by which the list needs to scroll in the vertical direction. If **listDirection** is set to **Axis.Horizontal**, the return value is the amount by which the list needs to scroll in the horizontal direction.|
| onScrollStart<sup>9+</sup>(event: () => void) | Triggered when the list starts scrolling initiated by the user's finger dragging the **\<Scroll>** component or its scrollbar. This event is also triggered when the animation contained in the scrolling triggered by [Scroller](ts-container-scroll.md#scroller) starts.<br>This API is supported in ArkTS widgets.|
| onScrollStop(event: () => void) | Triggered when the list 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.<br>Since API version 9, this API is supported in ArkTS widgets.|
| onItemMove(event: (from: number, to: number) => boolean) | Triggered when a list item moves.<br>- **from**: index of the item before moving.<br>- **to**: index of the item after moving.|
...
...
@@ -84,7 +104,7 @@ This API is supported in ArkTS widgets.
| onItemDragEnter(event: (event: ItemDragInfo) => void) | Triggered when the dragged item enters the drop target of the list.<br>- **event**: See [ItemDragInfo](ts-container-grid.md#itemdraginfo).|
| onItemDragMove(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number) => void) | Triggered when the dragged item moves over the drop target of the list.<br>- **event**: See [ItemDragInfo](ts-container-grid.md#itemdraginfo).<br>- **itemIndex**: initial position of the dragged item.<br>- **insertIndex**: index of the position to which the dragged item will be dropped.|
| onItemDragLeave(event: (event: ItemDragInfo, itemIndex: number) => void) | Triggered when the dragged item exits the drop target of the list.<br>- **event**: See [ItemDragInfo](ts-container-grid.md#itemdraginfo).<br>- **itemIndex**: index of the list item.|
| onItemDrop(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => void) | Triggered when the dragged item is dropped on the drop target of the list.<br>- **event**: See [ItemDragInfo](ts-container-grid.md#itemdraginfo).<br>- **itemIndex**: initial position of the dragged item.<br>- **insertIndex**: index of the position to which the dragged item will be dropped.<br>- **isSuccess**: whether the dragged item is successfully dropped.|
| onItemDrop(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => void) | Triggered when the dragged item is dropped on the drop target of the list.<br>- **event**: See [ItemDragInfo](ts-container-grid.md#itemdraginfo).<br>- **itemIndex**: initial position of the dragged item.<br>- **insertIndex**: index of the position to which the dragged item will be dropped.<br>- **isSuccess**: whether the dragged item is successfully dropped.<br>**NOTE**<br>During dragging across lists, **true** is returned if the drop target is bound to **onItemDrop**. Otherwise, **false** is returned. During dragging within a list, **isSuccess** is the return value of the **onItemMove** event.|
## ScrollState
...
...
@@ -92,9 +112,9 @@ Since API version 9, this API is supported in ArkTS widgets.
| Name | Description |
| ------ | ------------------------- |
| Idle | Not scrolling. |
| Scroll | Finger dragging. |
| Fling | Inertial scrolling. |
| Idle | Not scrolling. Triggered when the API provided by the controller is used to scroll the list or when the scrollbar is dragged.|
| Scroll | Finger dragging. Triggered when the user drags the list to scroll.|
| Fling | Inertial scrolling. Triggered when inertial scrolling occurs or when the list bounces back after being released from a quick swipe.|
> **NOTE**
>
...
...
@@ -121,43 +141,31 @@ Since API version 9, this API is supported in ArkTS widgets.
If developers use low-performance code to implement functions, the normal running of applications may not be affected, but the performance of applications may be adversely affected. This section lists some performance improvement scenarios for developers to avoid performance deterioration caused by application implementation.
Poor-performing code may work, but will take away from your application performance. This topic presents a line-up of recommendations that you can take to improve your implementation, thereby avoiding possible performance drop.
## Lazy data loading is recommended.
## Lazy Loading
If developers directly use the cyclic rendering mode when using a long list, as shown in the following figure, all list elements are loaded at a time. On one hand, the page startup takes a long time, affecting user experience. On the other hand, the pressure and traffic on the server increase, increasing the system load.
When developing a long list, use of loop rendering, as in the code snippet below, can greatly slow down page loading and increase server load.
```ts
@Entry
@Component
structMyComponent{
The@Statearr:number[]=Array.from(Array(100),(v,k)=>k);// constructs an array ranging from 0 to 99 and from 0 to 99.
@Statearr:number[]=Array.from(Array(100),(v,k)=>k);// Construct an array of 0 to 99.
build(){
List(){
ForEach(this.arr,(item:number)=>{
...
...
@@ -23,7 +23,7 @@ struct MyComponent {
}
```
The preceding code loads all 100 list elements during page loading, which is not required. We want to iteratively load data from the data source and create corresponding components. Therefore, data lazy loading is required, as shown in the following figure.
The preceding code snippet loads all of the 100 list elements at a time during page loading. This is generally not desirable. Instead, what we need is to load data from the data source and create corresponding components on demand. This can be achieved through lazy loading. The sample code is as follows:
```ts
classBasicDataSourceimplementsIDataSource{
...
...
@@ -129,11 +129,11 @@ struct MyComponent {
![LazyForEach1](figures/LazyForEach1.gif)
The preceding code initializes and loads only three list elements during page loading. Each time a list element is clicked, a list element is added.
The preceding code initializes only three list elements during page loading and loads a new list item each time a list element is clicked.
## Use conditional rendering to replace display and hiding control.
## Prioritizing Conditional Rendering over Visibility Control
As shown in the following figure, when developers use the visibility common attribute to control the display/hide status of a component, the component still needs to be re-created, causing performance loss.
Use of the visibility attribute to hide or show a component, as in the code snippet below, results in re-creation of the component, leading to performance drop.
```ts
@Entry
...
...
@@ -183,9 +183,9 @@ struct MyComponent {
![isVisible](figures/isVisible.gif)
## Replacing Flex with Column/Row
## Prioritizing Flex over Column/Row
By default, the Flex container component has shrink, which causes secondary layout. As a result, the page rendering performance deteriorates to some extent.
By default, the flex container needs to re-lay out flex items to comply with the **flexShrink** and **flexGrow** settings. This may result in drop in rendering performance.
```ts
@Entry
...
...
@@ -201,7 +201,7 @@ struct MyComponent {
}
```
In the preceding code, Flex can be replaced with Column and Row to avoid negative impacts caused by Flex secondary layout while ensuring that the page layout effect is the same.
To avoid the preceding issue, replace **Flex** with **Column** and **Row**, which can create the same page layout as **Flex** does.
```ts
@Entry
...
...
@@ -219,9 +219,9 @@ struct MyComponent {
![flex1](figures/flex1.PNG)
## Sets the width and height of the List component.
## Setting Width and Height for \<List> Components
When developers use the Scroll container component to embed the List child component, if the width and height of the List child component are not specified, all child components are loaded by default, as shown in the following figure.
When a **\<List>** component is nested within a **\<Scroll>** component, all of its content will be loaded if its width and height is not specified, which may result in performance drop.
```ts
@Entry
...
...
@@ -243,7 +243,7 @@ struct MyComponent {
}
```
Therefore, in this scenario, you are advised to set the width and height of the List child component as follows:
Therefore, in the above scenario, you are advised to set the width and height for the **\<List>** component as follows:
```ts
@Entry
...
...
@@ -267,11 +267,11 @@ struct MyComponent {
![list1](figures/list1.gif)
## Reduce application sliding white blocks.
## Minimizing White Blocks During Swiping
To minimize white blocks during swiping, expand the UI loading range by increasing the value of **cachedCount** for the **\<List>** and **\<Grid>** components. cachedCount indicates the number of items preloaded in the off-screen List/Grid.
If you need to request a network image, you can download the content in advance before the item slides to the screen to reduce the number of white blocks.
The following is an example of using the cachedCount parameter:
To minimize white blocks during swiping, expand the UI loading range by increasing the value of **cachedCount** for the **\<List>** and **\<Grid>** components. **cachedCount** indicates the number of list or grid items preloaded outside of the screen.
If an item needs to request an online image, set **cachedCount** as appropriate so that the image is downloaded in advance before the item comes into view on the screen, thereby reducing the number of white blocks.
The following is an example of using **cachedCount**:
```ts
@Entry
...
...
@@ -290,7 +290,7 @@ struct MyComponent {
})
}
})
}.cachedCount(3)//Increase the value. The appear log range will be enlarged.
}.cachedCount(3)// Increase the number of list or grid items preloaded outside of the screen.
}
}
...
...
@@ -314,5 +314,5 @@ class MyDataSource implements IDataSource {
```
![list2](figures/list2.gif)
**Instructions:**
**Instructions**
A greater **cachedCount** value may result in higher CPU and memory overhead of the UI. Adjust the value by taking into account both the comprehensive performance and user experience.