Class (DragController)
Provides APIs for initiating drag actions. When receiving a gesture event, such as a touch or long-press event, an application can initiate a drag action and carry drag information therein.
NOTE
The initial APIs of this module are supported since API version 10. Newly added APIs will be marked with a superscript to indicate their earliest API version.
The initial APIs of this class are supported since API version 11.
In the following API examples, you must first use getDragController() in UIContext to obtain a DragController instance, and then call the APIs using the obtained instance.
executeDrag11+
executeDrag(custom: CustomBuilder|DragItemInfo, dragInfo: dragController.DragInfo, callback: AsyncCallback<dragController.DragEventParam>): void
Initiates a drag action, with the object to be dragged and the drag information passed in. This API uses a callback to return the drag event result.
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 |
|---|---|---|---|
| custom | CustomBuilder |DragItemInfo | Yes | Object to be dragged. NOTE The global builder is not supported. If the Image component is used in the builder, enable synchronous loading, that is, set the syncLoad attribute of the component to true. The builder is used only to generate the image displayed during the current dragging. If the root component of the builder has zero width or height, it will cause failure in drag image generation, which in turn breaks the entire drag operation. Changes to the builder, if any, apply to the next dragging, but not to the current dragging. |
| dragInfo | dragController.DragInfo | Yes | Drag information. |
| callback | AsyncCallback<dragController.DragEventParam> | Yes | Callback used to return the result. - event: drag event information that includes only the drag result. - extraParams: extra information about the drag event. |
Error codes
For details about the error codes, see Universal Error Codes.
| ID | Error Message |
|---|---|
| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. |
| 100001 | Internal handling failed. |
Example
import { dragController } from '@kit.ArkUI';
import { unifiedDataChannel } from '@kit.ArkData';
class DragInfo {
event: DragEvent|undefined = undefined;
extraParams: string = '';
}
@Entry
@Component
struct DragControllerPage {
@Builder
DraggingBuilder() {
Column() {
Text("DraggingBuilder")
}
.width(100)
.height(100)
.backgroundColor(Color.Blue)
}
build() {
Column() {
Button('touch to execute drag')
.onTouch((event?: TouchEvent) => {
if (event) {
if (event.type == TouchType.Down) {
let text = new unifiedDataChannel.Text();
let unifiedData = new unifiedDataChannel.UnifiedData(text);
let dragInfo: dragController.DragInfo = {
pointerId: 0,
data: unifiedData,
extraParams: ''
};
let eve: DragInfo = new DragInfo();
this.getUIContext().getDragController().executeDrag(() => {
this.DraggingBuilder()
}, dragInfo, (err, eve) => {
if (eve.event) {
if (eve.event.getResult() == DragResult.DRAG_SUCCESSFUL) {
// ...
} else if (eve.event.getResult() == DragResult.DRAG_FAILED) {
// ...
}
}
})
}
}
})
}
.width('100%')
.height('100%')
}
}

executeDrag11+
executeDrag(custom: CustomBuilder|DragItemInfo, dragInfo: dragController.DragInfo): Promise<dragController.DragEventParam>
Initiates a drag action, with the object to be dragged and the drag information passed in. This API uses a promise to return the drag event result.
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 |
|---|---|---|---|
| custom | CustomBuilder |DragItemInfo | Yes | Object to be dragged. |
| dragInfo | dragController.DragInfo | Yes | Drag information. |
Return value
| Type | Description |
|---|---|
| Promise<dragController.DragEventParam> | Callback used to return the result. - event: drag event information that includes only the drag result. - extraParams: extra information about the drag event. |
Error codes
For details about the error codes, see Universal Error Codes.
| ID | Error Message |
|---|---|
| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. |
| 100001 | Internal handling failed. |
Example
import { dragController } from '@kit.ArkUI';
import { image } from '@kit.ImageKit';
import { unifiedDataChannel } from '@kit.ArkData';
class DragInfo {
event: DragEvent|undefined = undefined;
extraParams: string = '';
}
@Entry
@Component
struct DragControllerPage {
@State pixmap: image.PixelMap|null = null;
@Builder
DraggingBuilder() {
Column() {
Text("DraggingBuilder")
}
.width(100)
.height(100)
.backgroundColor(Color.Blue)
}
@Builder
PixmapBuilder() {
Column() {
Text("PixmapBuilder")
}
.width(100)
.height(100)
.backgroundColor(Color.Blue)
}
build() {
Column() {
Button('touch to execute drag')
.onTouch((event?: TouchEvent) => {
if (event) {
if (event.type == TouchType.Down) {
let text = new unifiedDataChannel.Text();
let unifiedData = new unifiedDataChannel.UnifiedData(text);
let dragInfo: dragController.DragInfo = {
pointerId: 0,
data: unifiedData,
extraParams: ''
};
let pb: CustomBuilder = (): void => {
this.PixmapBuilder()
};
this.getUIContext().getComponentSnapshot().createFromBuilder(pb).then((pix: image.PixelMap) => {
this.pixmap = pix;
let dragItemInfo: DragItemInfo = {
pixelMap: this.pixmap,
builder: () => {
this.DraggingBuilder()
},
extraInfo: "DragItemInfoTest"
};
let eve: DragInfo = new DragInfo();
this.getUIContext()
.getDragController()
.executeDrag(dragItemInfo, dragInfo)
.then((eve) => {
if (eve.event.getResult() == DragResult.DRAG_SUCCESSFUL) {
// ...
} else if (eve.event.getResult() == DragResult.DRAG_FAILED) {
// ...
}
})
.catch((err: Error) => {
})
})
}
}
})
}
.width('100%')
.height('100%')
}
}

createDragAction11+
createDragAction(customArray: Array<CustomBuilder |DragItemInfo>, dragInfo: dragController.DragInfo): dragController.DragAction
Creates a drag action object for initiating drag and drop operations. You need to explicitly specify one or more drag previews, the drag data, and the drag handle point. If a drag operation initiated by an existing drag action object is not completed, no new object can be created, and calling the API will throw an exception. After the lifecycle of the drag action object ends, the callback functions registered on this object become invalid. Therefore, it is necessary to hold this object within a longer scope and replace the old value with a new object returned by createDragAction before each drag initiation.
NOTE
For optimal drag and drop performance, limit the number of drag previews.
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 |
|---|---|---|---|
| customArray | Array<CustomBuilder |DragItemInfo> | Yes | Object to be dragged. |
| dragInfo | dragController.DragInfo | Yes | Drag information. |
Return value
| Type | Description |
|---|---|
| dragController.DragAction | DragAction object, which is used to subscribe to drag state changes and start the drag service. |
Error codes
For details about the error codes, see Universal Error Codes.
| ID | Error Message |
|---|---|
| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. |
| 100001 | Internal handling failed. |
Example
- In the EntryAbility.ets file, obtain the UI context and save it to LocalStorage.
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window, UIContext } from '@kit.ArkUI';
let uiContext: UIContext;
let localStorage: LocalStorage = new LocalStorage('uiContext');
export default class EntryAbility extends UIAbility {
storage: LocalStorage = localStorage;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy(): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', this.storage, (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
windowStage.getMainWindow((err, data) => {
if (err.code) {
console.error(`Failed to obtain the main window. Cause:${err.message}`);
return;
}
let windowClass: window.Window = data;
uiContext = windowClass.getUIContext();
this.storage.setOrCreate<UIContext>('uiContext', uiContext);
// Obtain a UIContext instance.
});
});
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground(): void {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}
- Call this.getUIContext().getSharedLocalStorage() to obtain the UI context and then use the DragController object obtained to perform subsequent operations.
import { dragController, componentSnapshot, UIContext, DragController } from '@kit.ArkUI';
import { image } from '@kit.ImageKit';
import { unifiedDataChannel } from '@kit.ArkData';
@Entry()
@Component
struct DragControllerPage {
@State pixmap: image.PixelMap|null = null;
private dragAction: dragController.DragAction|null = null;
customBuilders: Array<CustomBuilder|DragItemInfo> = new Array<CustomBuilder|DragItemInfo>();
storages = this.getUIContext().getSharedLocalStorage();
@Builder
DraggingBuilder() {
Column() {
Text("DraggingBuilder")
}
.width(100)
.height(100)
.backgroundColor(Color.Blue)
}
build() {
Column() {
Button('Drag Multiple Objects').onTouch((event?: TouchEvent) => {
if (event) {
if (event.type == TouchType.Down) {
console.info("multi drag Down by listener");
this.customBuilders.push(() => {
this.DraggingBuilder()
});
this.customBuilders.push(() => {
this.DraggingBuilder()
});
this.customBuilders.push(() => {
this.DraggingBuilder()
});
let text = new unifiedDataChannel.Text();
let unifiedData = new unifiedDataChannel.UnifiedData(text);
let dragInfo: dragController.DragInfo = {
pointerId: 0,
data: unifiedData,
extraParams: ''
};
try {
let uiContext: UIContext = this.storages?.get<UIContext>('uiContext') as UIContext;
this.dragAction = uiContext.getDragController().createDragAction(this.customBuilders, dragInfo);
if (!this.dragAction) {
console.info("listener dragAction is null");
return;
}
this.dragAction.on('statusChange', (dragAndDropInfo) => {
if (dragAndDropInfo.status == dragController.DragStatus.STARTED) {
console.info("drag has start");
} else if (dragAndDropInfo.status == dragController.DragStatus.ENDED) {
console.info("drag has end");
if (!this.dragAction) {
return;
}
this.customBuilders.splice(0, this.customBuilders.length);
this.dragAction.off('statusChange');
}
})
this.dragAction.startDrag().then(() => {
}).catch((err: Error) => {
console.error(`start drag Error:${err.message}`);
})
} catch (err) {
console.error(`create dragAction Error:${err.message}`);
}
}
}
}).margin({ top: 20 })
}
.width('100%')
.height('100%')
}
}

getDragPreview11+
getDragPreview(): dragController.DragPreview
Obtains the DragPreview object, which represents the preview displayed during a drag operation.
Atomic service API: This API can be used in atomic services since API version 12.
System capability: SystemCapability.ArkUI.ArkUI.Full
Return value
| Type | Description |
|---|---|
| dragController.DragPreview | DragPreview object. It provides the API for setting the preview style. It does not work in the OnDrop and OnDragEnd callbacks. |
Error codes: For details about universal error codes, see Universal Error Codes.
Example
See the example for animate.
setDragEventStrictReportingEnabled12+
setDragEventStrictReportingEnabled(enable: boolean): void
Sets whether the onDragLeave callback of the parent component is triggered when an item is dragged from the parent to the child component.
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 |
|---|---|---|---|
| enable | boolean | Yes | Whether the onDragLeave callback of the parent component is triggered when an item is dragged from the parent to the child component. The value true means the onDragLeave callback of the parent component is triggered, and false means the opposite. |
Example
import { UIAbility } from '@kit.AbilityKit';
import { window, UIContext } from '@kit.ArkUI';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
return;
}
windowStage.getMainWindow((err, data) => {
if (err.code) {
return;
}
let windowClass: window.Window = data;
let uiContext: UIContext = windowClass.getUIContext();
uiContext.getDragController().setDragEventStrictReportingEnabled(true);
});
});
}
}
cancelDataLoading15+
cancelDataLoading(key: string): void
Cancels the data loading initiated by the startDataLoading API. This API can be called only after the drag is released.
Atomic service API: This API can be used in atomic services since API version 15.
System capability: SystemCapability.ArkUI.ArkUI.Full
Parameters
| Name | Type | Mandatory | Description |
|---|---|---|---|
| key | string | Yes | Identifier for the drag data. It is used to distinguish between different drag operations. The key can be obtained through the startDataLoading API. |
Error codes
For details about the error codes, see Universal Error Codes and Drag Event Error Codes.
| ID | Error Message |
|---|---|
| 401 | Parameter error. |
| 190004 | Operation failed. |
notifyDragStartRequest18+
notifyDragStartRequest(requestStatus: dragController.DragStartRequestStatus): void
Controls whether the application can initiate a drag operation.
Atomic service API: This API can be used in atomic services since API version 18.
System capability: SystemCapability.ArkUI.ArkUI.Full
Parameters
| Name | Type | Mandatory | Description |
|---|---|---|---|
| requestStatus | dragController.DragStartRequestStatus | Yes | Whether the application can initiate a drag operation. |
Example
// xxx.ets
import { unifiedDataChannel } from '@kit.ArkData';
import { image } from '@kit.ImageKit';
import { dragController } from '@kit.ArkUI';
@Entry
@Component
struct NormalEts {
@State finished: boolean = false;
@State timeout1: number = 1;
@State pixmap: image.PixelMap|undefined = undefined;
@State unifiedData1: unifiedDataChannel.UnifiedData|undefined = undefined;
@State previewData: DragItemInfo|undefined = undefined;
loadData() {
// Set a 4-second delay before initiating a drag action.
let timeout = setTimeout(() => {
this.getUIContext().getComponentSnapshot().get("image1", (error: Error, pixmap: image.PixelMap) => {
this.pixmap = pixmap;
this.previewData = {
pixelMap: this.pixmap
};
});
let data: unifiedDataChannel.Image = new unifiedDataChannel.Image();
data.imageUri = "app.media.startIcon";
let unifiedData = new unifiedDataChannel.UnifiedData(data);
this.unifiedData1 = unifiedData;
this.getUIContext().getDragController().notifyDragStartRequest(dragController.DragStartRequestStatus.READY);
}, 4000);
this.timeout1 = timeout;
}
build() {
Column({ space: 20 }) {
Image($r("app.media.startIcon"))
.width(150)
.height(150)
.id("image1")
.draggable(true)
.dragPreview(this.previewData)
.onPreDrag((status: PreDragStatus) => {
if (status == PreDragStatus.PREPARING_FOR_DRAG_DETECTION) {
this.loadData();
} else {
clearTimeout(this.timeout1);
}
})
.onDragStart((event: DragEvent) => {
if (this.finished == false) {
this.getUIContext()
.getDragController()
// In the application data preparation phase, a drag action cannot be initiated.
.notifyDragStartRequest(dragController.DragStartRequestStatus.WAITING);
} else {
event.setData(this.unifiedData1);
}
})
.onDragEnd(() => {
this.finished = false;
})
}
.width('100%')
.height(400)
}
}

enableDropDisallowedBadge20+
enableDropDisallowedBadge(enabled: boolean): void
Specifies whether to enable the display of a disallowed badge when dragged content is incompatible with a component's configured allowDrop types. When a component can accept or process dragged data or returns DragBehavior.COPY to indicate copy mode processing, the drag preview shows a plus icon with data count badge. When the component returns DragBehavior.MOVE to indicate cut mode processing, only the data count badge appears. When this feature is enabled, the system automatically displays a disallowed badge during drag operations if the dragged data types are incompatible with the target component's allowed drop types. This API currently does not support UIExtension.
Atomic service API: This API can be used in atomic services since API version 20.
System capability: SystemCapability.ArkUI.ArkUI.Full
Parameters
| Name | Type | Mandatory | Description |
|---|---|---|---|
| enabled | boolean | Yes | Whether to enable the display of a disallowed badge when dragged content is incompatible with a component's configured allowDrop types. The value true means to enable the display of a disallowed badge, and false means the opposite. The default value is false. |
Example
This example demonstrates how to use the enableDropDisallowedBadge API to enable the display of a disallowed badge when dragged content is incompatible with the target component's allowed drop types.
-
Call the enableDropDisallowedBadge API in EntryAbility.ets and set the enabled parameter to true.
import { UIAbility } from '@kit.AbilityKit'; import { window, UIContext } from '@kit.ArkUI'; export default class EntryAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage): void { windowStage.loadContent('pages/Index', (err, data) => { if (err.code) { return; } windowStage.getMainWindow((err, data) => { if (err.code) { return; } let windowClass: window.Window = data; let uiContext: UIContext = windowClass.getUIContext(); uiContext.getDragController().enableDropDisallowedBadge(true); }); }); } } -
Drag the icon to the blank area below in Index.ets. The drag-disallowed badge is displayed.
@Entry @Component struct Index { build() { Column({ space: 20 }) { // Replace $r('app.media.startIcon') with the image resource file you use. Image($r('app.media.startIcon')) .width(120) .height(120) Text ('Invalid drop zone.') Column() .width('100%') .layoutWeight(1) .allowDrop(null) .onDrop(() => { }) }.width('100%') } }

你可能感兴趣的鸿蒙文章
openharmony 鸿蒙 arkts-apis-uicontext-contextmenucontroller
openharmony 鸿蒙 errorcode-canvas
openharmony 鸿蒙 capi-oh-nativexcomponent-native-xcomponent-oh-nativexcomponent
openharmony 鸿蒙 errorcode-bindSheet
openharmony 鸿蒙 js-apis-arkui-uiExtension-sys
openharmony 鸿蒙 capi-arkui-accessibility-arkui-accessibilityeventinfo
openharmony 鸿蒙 capi-arkui-rendernodeutils
openharmony 鸿蒙 js-apis-arkui-node
openharmony 鸿蒙 capi-native-node-h
openharmony 鸿蒙 capi-arkui-nativemodule-arkui-listitemswipeactionitem