## How do I implement the dragging feature for the \<Grid> component?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9)
**Solution**
1. Set the **editMode\(true\)** attribute of the **\<Grid>** component to specify whether the component enters the editing mode. In the editing mode, you can drag grid items.
2. Set the image displayed during dragging in the [onItemDragStart](../reference/arkui-ts/ts-container-grid.md#events) callback.
3. Obtain the drag start position and drag insertion position from the [onItemDrop](../reference/arkui-ts/ts-container-grid.md#events) callback, and complete the array position exchange logic in the [onDrag](../reference/arkui-ts/ts-universal-events-drag-drop.md#events) callback. The sample code is as follows:
```
@Entry
@Component
struct GridExample {
@State numbers: String[] = []
scroller: Scroller = new Scroller()
@State text: string = 'drag'
@Builder pixelMapBuilder () { // Drag style
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 item position.
.editMode(true) // Set whether the grid enters the editing mode. In the editing mode, you can drag grid items.
.onItemDragStart((event: ItemDragInfo, itemIndex: number) => { // Triggered when a grid item starts to be dragged.
return this.pixelMapBuilder() // Set the image 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.
console.info('beixiang' + itemIndex + '', insertIndex + '') // itemIndex indicates the initial position of the dragged item; insertIndex indicates the index of the position to which the dragged item will be dropped.
## Can custom dialog boxes be defined or used in .ts files?
## Can custom dialog boxes be defined and used in .ts files?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
Unfortunately, no. ArkTS syntax is required for defining and initializing custom dialog boxes. Therefore, they can be defined and used only in .ets files.
Unfortunately not. Custom dialog boxes require ArkTS syntax for definition and initialization. Therefore, they can be defined and used only in .ets files.
**Reference**
**Reference**
...
@@ -245,8 +245,8 @@ When a custom dialog box contains a child component whose area size can be chang
...
@@ -245,8 +245,8 @@ When a custom dialog box contains a child component whose area size can be chang
**Solution**
**Solution**
- Method 1: Use the default style of the custom dialog box. In this case, the dialog box automatically adapts its width to the grid system and its height to the child components; the maximum height is 90% of the container height.
- Method 1: Set the custom dialog box to the default style. In this style, the dialog box automatically adapts its width to the grid system and its height to the child components; the maximum height is 90% of the container height.
- Method 2: Use a custom style of the custom dialog box. In this case, the dialog box automatically adapts its width and height to the child components.
- Method 2: Set the custom dialog box to a custom style. In this style, the dialog box automatically adapts its width and height to the child components.
**Reference**
**Reference**
...
@@ -685,3 +685,64 @@ You can use **focusControl.requestFocus** to control the focus of the text input
...
@@ -685,3 +685,64 @@ You can use **focusControl.requestFocus** to control the focus of the text input
@@ -240,6 +240,8 @@ To reference an application resource in a project, use the **"$r('app.type.name'
...
@@ -240,6 +240,8 @@ To reference an application resource in a project, use the **"$r('app.type.name'
When referencing resources in the **rawfile** subdirectory, use the **"$rawfile('filename')"** format. Wherein **filename** indicates the relative path of a file in the **rawfile** subdirectory, which must contain the file name extension and cannot start with a slash (/).
When referencing resources in the **rawfile** subdirectory, use the **"$rawfile('filename')"** format. Wherein **filename** indicates the relative path of a file in the **rawfile** subdirectory, which must contain the file name extension and cannot start with a slash (/).
To obtain the descriptor of a file in the **rawfile** subdirectory, you can use the [getRawFd](../reference/apis/js-apis-resource-manager.md#getrawfd9) API, whose return value **descriptor.fd** is the file descriptor (FD). To access the file with this FD, use {fd, offset, length}.
> **NOTE**
> **NOTE**
>
>
> Resource descriptors accept only strings, such as **'app.type.name'**, and cannot be combined.
> Resource descriptors accept only strings, such as **'app.type.name'**, and cannot be combined.
...
@@ -284,7 +286,7 @@ To reference a system resource, use the **"$r('sys.type.resource_id')"** format.
...
@@ -284,7 +286,7 @@ To reference a system resource, use the **"$r('sys.type.resource_id')"** format.
> **NOTE**
> **NOTE**
>
>
> - Use of system resources is supported in the declarative development paradigm, but not in the web-like development paradigm.
> - The use of system resources is supported in the declarative development paradigm, but not in the web-like development paradigm.
>
>
> - For details about the implementation of preconfigured resources, visit the [OpenHarmony/resources repository](https://gitee.com/openharmony/resources/tree/master/systemres/main/resources). The directory structure there is similar to that of the **resources** directory in the project. Resource qualifiers are used to match resources with different devices and device states.
> - For details about the implementation of preconfigured resources, visit the [OpenHarmony/resources repository](https://gitee.com/openharmony/resources/tree/master/systemres/main/resources). The directory structure there is similar to that of the **resources** directory in the project. Resource qualifiers are used to match resources with different devices and device states.
@@ -23,10 +23,11 @@ The **\<Grid>** component accepts only **\<[GridItem](ts-container-griditem.md)>
...
@@ -23,10 +23,11 @@ The **\<Grid>** component accepts only **\<[GridItem](ts-container-griditem.md)>
>
>
> 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.
> 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.
> The child component that has the **visibility** attribute set to **Hidden** or **None** is 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.
> 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 takes up the corresponding cell, and is 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.
## APIs
## APIs
...
@@ -44,8 +45,8 @@ In addition to the [universal attributes](ts-universal-attributes-size.md), the
...
@@ -44,8 +45,8 @@ In addition to the [universal attributes](ts-universal-attributes-size.md), the
| Name| Type| Description|
| 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.<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.|
| columnsTemplate | string | Number of columns in the current grid layout. If this attribute is not set, one column will be used.<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.|
| rowsTemplate | string | Number of rows in the current grid layout. If this attribute is not set, one row will be used.<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.|
| 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.|
| 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.|
| scrollBar | [BarState](ts-appendix-enums.md#barstate) | Scrollbar status.<br>Default value: **BarState.Off**<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**.|
| scrollBar | [BarState](ts-appendix-enums.md#barstate) | Scrollbar status.<br>Default value: **BarState.Off**<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**.|
...
@@ -70,10 +71,6 @@ Depending on the settings of the **rowsTemplate** and **columnsTemplate** attrib
...
@@ -70,10 +71,6 @@ Depending on the settings of the **rowsTemplate** and **columnsTemplate** attrib
- If the width and height of a grid are not set, the grid adapts to the size of its parent component by default.
- 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.
- 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.
- 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
2. Either **rowsTemplate** or **columnsTemplate** is set
...
@@ -83,19 +80,14 @@ Depending on the settings of the **rowsTemplate** and **columnsTemplate** attrib
...
@@ -83,19 +80,14 @@ Depending on the settings of the **rowsTemplate** and **columnsTemplate** attrib
- In this mode, the following attributes do not take effect: **layoutDirection**, **maxCount**, minCount, and **cellLength**.
- 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 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.
- 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
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 **\<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.
- 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**.
- 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 **Row**, elements are arranged row by row from left to right. 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 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.
- 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.
- In this mode, **rowStart** and **columnStart** of the grid item do not take effect.
## GridDirection<sup>8+</sup>
## GridDirection<sup>8+</sup>
...
@@ -116,11 +108,11 @@ In addition to the [universal events](ts-universal-events-click.md), the followi
...
@@ -116,11 +108,11 @@ In addition to the [universal events](ts-universal-events-click.md), the followi
| Name| Description|
| Name| Description|
| -------- | -------- |
| -------- | -------- |
| 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.|
| onScrollIndex(event: (first: number) => void) | Triggered when the first item displayed in the grid changes. It is triggered once when the grid is initialized.<br>- **first**: index of the first 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.|
| 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 item.<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).|
| 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.|
| 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.|
| onItemDragLeave(event: (event: ItemDragInfo, itemIndex: number) => void) | Triggered when the dragged item leaves the drop target of the grid.<br>- **event**: See [ItemDragInfo](#itemdraginfo).<br>- **itemIndex**: index of the dragged 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 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.<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 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.<br>- **isSuccess**: whether the dragged item is successfully dropped.|
## ItemDragInfo
## ItemDragInfo
...
@@ -132,6 +124,8 @@ In addition to the [universal events](ts-universal-events-click.md), the followi
...
@@ -132,6 +124,8 @@ In addition to the [universal events](ts-universal-events-click.md), the followi
1. Set **editMode\(true\)** to enable the grid to enter editing mode, where the user can drag the grid items.
2. Through [onItemDragStart](#events), set the image to be displayed during dragging.
3. Through [onItemDrop](#events), obtain the initial position of the dragged item and the position to which the dragged item will be dropped. Through [onDrag](#events), complete the array position exchange logic.
```ts
@Entry
@Component
structGridExample{
@Statenumbers:String[]=[]
scroller:Scroller=newScroller()
@Statetext:string='drag'
@BuilderpixelMapBuilder(){// Style for the drag event.
Column(){
Text(this.text)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width(80)
.height(80)
.textAlign(TextAlign.Center)
}
}
aboutToAppear(){
for(leti=1;i<=15;i++){
this.numbers.push(i+'')
}
}
changeIndex(index1:number,index2:number){// Exchange the array position.
.editMode(true)// Enable the grid to enter editing mode, where the user can drag the grid items.
.onItemDragStart((event:ItemDragInfo,itemIndex:number)=>{// Triggered when a grid item starts to be dragged.
returnthis.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.
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.
> - Settings outside of the valid ranges do not take effect.
> - Settings outside of the valid ranges do not take effect.
>
>
> - In the grid that has both **columnTemplate** and **rowTemplate** set, a grid item takes up the specified number of rows (rowEnd – rowStart + 1) or columns (columnEnd – columnStart + 1), depending on whether **rowStart**/**rowEnd** or **columnStart**/**columnEnd** is set.
> - In the grid that has both **columnTemplate** and **rowTemplate** set, a grid item takes up the specified number of rows (rowEnd – rowStart + 1) or columns (columnEnd – columnStart + 1), depending on whether **rowStart**/**rowEnd** or **columnStart**/**columnEnd** is set.
>- In the grid that has only **columnTemplate** set, a grid item takes up the specified number of columns.
>- In the grid that has only **columnTemplate** set, a grid item takes up the specified number of columns.
> - In the grid that has only **rowTemplate** set, a grid item takes up the specified number of rows.
> - In the grid that has only **rowTemplate** set, a grid item takes up the specified number of rows.
>- In the grid that has neither **columnTemplate** nor **rowTemplate** set, the row and column number attributes do not work.
>- In the grid that has neither **columnTemplate** nor **rowTemplate** set, the row and column number attributes do not work.