@ohos.arkui.dragController (DragController)

The dragController module 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 functionality of this module depends on UI context. This means that the APIs of this module cannot be used where the UI context is unclear. For details, see UIContext. Since API version 10, you can use the getDragController API in UIContext to obtain the DragController object associated with the current UI context. You can preview how this component looks on a real device, but not in DevEco Studio Previewer.

Modules to Import

import dragController from "@ohos.arkui.dragController";

dragController.executeDrag

executeDrag(custom: CustomBuilder | DragItemInfo, dragInfo: DragInfo, callback: AsyncCallback< {event: DragEvent, extraParams: string}>): void

Initiates a drag action, with the object to be dragged and the drag information passed in. This API uses an asynchronous callback to return the result.

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. Changes to the builder, if any, apply to the next dragging, but not to the current dragging.
dragInfo DragInfo Yes Drag information.
callback AsyncCallback<{event: DragEvent, extraParams: string}> 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

ID Error Message
401 if the parameters checking failed.
100001 if some internal handling failed.

Example

import dragController from "@ohos.arkui.dragController"
import UDC from '@ohos.data.unifiedDataChannel';

@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 UDC.Text()
              let unifiedData = new UDC.UnifiedData(text)

              let dragInfo: dragController.DragInfo = {
                pointerId: 0,
                data: unifiedData,
                extraParams: ''
              }
              class tmp{
                event:DragEvent|undefined = undefined
                extraParams:string = ''
              }
              let eve:tmp = new tmp()
              dragController.executeDrag(()=>{this.DraggingBuilder()}, dragInfo, (err, eve) => {
                if(eve.event){
                  if (eve.event.getResult() == DragResult.DRAG_SUCCESSFUL) {
                  // ...
                  } else if (eve.event.getResult() == DragResult.DRAG_FAILED) {
                  // ...
                  }
                }
              })
            }
          }
        })
    }
  }
}

dragController.executeDrag

executeDrag(custom: CustomBuilder | DragItemInfo, dragInfo: DragInfo): Promise<{event: DragEvent, extraParams: string}>

Initiates a drag action, with the object to be dragged and the drag information passed in. This API uses a promise to return the result.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
custom CustomBuilder | DragItemInfo Yes Object to be dragged.
dragInfo DragInfo Yes Drag information.

Return value

Type Description
Promise<{event: DragEvent, extraParams: string}> Promise used to return the result.
- event: drag event information that includes only the drag result.
- extraParams: extra information about the drag event.

Error codes

ID Error Message
401 if the parameters checking failed.
100001 if some internal handling failed.

Example

import dragController from "@ohos.arkui.dragController"
import componentSnapshot from '@ohos.arkui.componentSnapshot';
import image from '@ohos.multimedia.image';
import UDC from '@ohos.data.unifiedDataChannel';

@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 UDC.Text()
              let unifiedData = new UDC.UnifiedData(text)

              let dragInfo: dragController.DragInfo = {
                pointerId: 0,
                data: unifiedData,
                extraParams: ''
              }
              let pb:CustomBuilder = ():void=>{this.PixmapBuilder()}
              componentSnapshot.createFromBuilder(pb).then((pix: image.PixelMap) => {
                this.pixmap = pix;
                let dragItemInfo: DragItemInfo = {
                  pixelMap: this.pixmap,
                  builder: ()=>{this.DraggingBuilder()},
                  extraInfo: "DragItemInfoTest"
                }

                class tmp{
                  event:DragResult|undefined = undefined
                  extraParams:string = ''
                }
                let eve:tmp = new tmp()
                dragController.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%')
  }
}

DragInfo

System capability: SystemCapability.ArkUI.ArkUI.Full

Defines the attributes required for initiating a drag action and information carried in the dragging process.

Name Type Mandatory Description
pointerId number Yes ID of the touch point on the screen when dragging is started.
data unifiedDataChannel.UnifiedData No Data carried in the dragging process.
extraParams string No Additional information about the drag action. Not supported currently.
touchPoint11+ TouchPoint No Coordinates of the touch point. If this parameter is not set, the touch point is centered.
previewOptions11+ DragPreviewOptions No Custom configuration of the drag preview.

DragStatus11+

System capability: SystemCapability.ArkUI.ArkUI.Full

Describes the dragging start and end states.

Name Value Description
STARTED 0 Dragging is started.
ENDED 1 Dragging ends.

DragAndDropInfo11+

System capability: SystemCapability.ArkUI.ArkUI.Full

Provides the data reported when the state changes during dragging.

Name Type Mandatory Description
status DragStatus Yes Current dragging state (started or ended).
event DragEvent No Drag event corresponding to the current state.
extraParams string No Additional information about the drag action. Not supported currently.

DragAction11+

Implements a DragAction object to subscribe to drag state changes and start the drag service.

System capability: SystemCapability.ArkUI.ArkUI.Full

startDrag11+

startDrag(): Promise<void>

Starts the drag service. This API uses a promise to return the result.

System capability: SystemCapability.ArkUI.ArkUI.Full

Error codes

ID Error Message
100001 if some internal handling failed.

Example

import dragController from "@ohos.arkui.dragController"
import UDC from '@ohos.data.unifiedDataChannel';
let customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>();
let text = new UDC.Text()
let unifiedData = new UDC.UnifiedData(text)
let dragInfo: dragController.DragInfo = {
  pointerId: 0,
  data: unifiedData,
  extraParams: ''
}
try{
  let dragAction: dragController.DragAction | null = dragController.createDragAction(customBuilders, dragInfo);
  if(!dragAction){
    console.log("listener dragAction is null");
    return
  }
  dragAction.startDrag().then(()=>{}).catch((err:Error)=>{
    console.log("start drag Error:" + err.message);
  })
}catch(err) {
  console.log("create dragAction Error:" + err.message);
}

on('statusChange')11+

on(type: 'statusChange', callback: Callback<DragAndDropInfo>): void

Subscribes to drag state changes.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
type string Yes Event type. The value is fixed at 'statusChange', which indicates the drag state change event.
callback Callback<DragAndDropInfo> Yes Callback used to return a DragAndDropInfo instance.

Example

import dragController from "@ohos.arkui.dragController"
import UDC from '@ohos.data.unifiedDataChannel';
let customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>();
let text = new UDC.Text()
let unifiedData = new UDC.UnifiedData(text)
let dragInfo: dragController.DragInfo = {
  pointerId: 0,
  data: unifiedData,
  extraParams: ''
}
try{
  let dragAction: dragController.DragAction | null = dragController.createDragAction(customBuilders, dragInfo);
  if(!dragAction){
    console.log("listener dragAction is null");
    return
  }
  dragAction.on('statusChange', (dragAndDropInfo: dragController.DragAndDropInfo)=>{
    console.info("Register to listen on drag status", JSON.stringify(dragAndDropInfo));
  })
}catch(err) {
  console.log("create dragAction Error:" + err.message);
}

off('statusChange')11+

off(type: 'statusChange', callback?: Callback<DragAndDropInfo>): void

Unsubscribes from drag state changes.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
type string Yes Event type. The value is fixed at 'statusChange', which indicates the drag state change event.
callback Callback<DragAndDropInfo> No Callback used to return a DragAndDropInfo instance. If this parameter is not set, this API unsubscribes from all callbacks corresponding to type.

Example

import dragController from "@ohos.arkui.dragController"
import UDC from '@ohos.data.unifiedDataChannel';
let customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>();
let text = new UDC.Text()
let unifiedData = new UDC.UnifiedData(text)
let dragInfo: dragController.DragInfo = {
  pointerId: 0,
  data: unifiedData,
  extraParams: ''
}
try{
  let dragAction: dragController.DragAction | null = dragController.createDragAction(customBuilders, dragInfo);
  if(!dragAction){
    console.log("listener dragAction is null");
    return
  }
  dragAction.off('statusChange', (dragAndDropInfo: dragController.DragAndDropInfo)=>{
    console.info("Cancel listening on drag status", JSON.stringify(dragAndDropInfo));
  })
}catch(err) {
  console.log("create dragAction Error:" + err.message);
}

dragController.createDragAction11+

createDragAction(customArray: Array<CustomBuilder | DragItemInfo>, dragInfo: DragInfo): DragAction

Creates a DragAction object, by explicitly specifying one or more drag previews, drag data, and information about the dragged object. If the drag initiated by a DragAction object is not complete, no new DragAction object can be created, and calling this API will throw an exception.

NOTE
You are advised to control the number of drag previews. If too many previews are passed in, the drag efficiency may be affected.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
customArray Array<CustomBuilder | DragItemInfo> Yes Object to be dragged.
dragInfo DragInfo Yes Drag information.

Return value

Type Description
DragAction DragAction object, which is used to subscribe to drag state changes and start the drag service.

Error codes

ID Error Message
401 Invalid input parameter
100001 If some internal handling failed

Example

import dragController from "@ohos.arkui.dragController"
import componentSnapshot from '@ohos.arkui.componentSnapshot';
import image from '@ohos.multimedia.image';
import UDC from '@ohos.data.unifiedDataChannel';

@Entry
@Component
struct DragControllerPage {
  @State pixmap: image.PixelMap | null = null
  private dragAction: dragController.DragAction | null = null;
  customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>();
  @Builder DraggingBuilder() {
    Column() {
      Text("DraggingBuilder")
    }
    .width(100)
    .height(100)
    .backgroundColor(Color.Blue)
  }

  build() {
    Column() {

      Column() {
        Text ("Test")
      }
      .width(100)
      .height(100)
      .backgroundColor(Color.Red)

      Button('Drag Multiple Objects').onTouch((event?:TouchEvent) => {
        if(event){
          if (event.type == TouchType.Down) {
            console.log("muti drag Down by listener");
            this.customBuilders.splice(0, this.customBuilders.length);
            this.customBuilders.push(()=>{this.DraggingBuilder()});
            this.customBuilders.push(()=>{this.DraggingBuilder()});
            this.customBuilders.push(()=>{this.DraggingBuilder()});
            let text = new UDC.Text()
            let unifiedData = new UDC.UnifiedData(text)
            let dragInfo: dragController.DragInfo = {
              pointerId: 0,
              data: unifiedData,
              extraParams: ''
            }
            try{
              this.dragAction = dragController.createDragAction(this.customBuilders, dragInfo)
            if(!this.dragAction){
              console.log("listener dragAction is null");
              return
            }
            this.dragAction.on('statusChange', (dragAndDropInfo: dragController.DragAndDropInfo)=>{
              if (dragAndDropInfo.status == dragController.DragStatus.STARTED) {
                console.log("drag has start");
              } else if (dragAndDropInfo.status == dragController.DragStatus.ENDED){
                console.log("drag has end");
                if (!this.dragAction) {
                  return
                }
                this.dragAction.off('statusChange')
              }
            })
            this.dragAction.startDrag().then(()=>{}).catch((err:Error)=>{
              console.log("start drag Error:" + err.message);
            })
            } catch(err) {
              console.log("create dragAction Error:" + err.message);
            }
          }
        }
      }).margin({top:20})
    }
  }
}

AnimationOptions11+

System capability: SystemCapability.ArkUI.ArkUI.Full

Defines the attributes required for initiating a drag action and information carried in the dragging process.

Name Type Mandatory Description
duration number No Animation duration, in ms.
Default value: 1000
NOTE
- If this parameter is set to a value less than 0, the value 0 is used.
- Floating-point values will be rounded down to integers. For example, if the value set is 1.2, 1 will be used.
curve Curve | ICurve No Animation curve.
Default value: Curve.EaseInOut

dragController.getDragPreview11+

getDragPreview(): DragPreview

Obtains the DragPreview object, which represents the preview displayed during a drag.

System capability: SystemCapability.ArkUI.ArkUI.Full

Return value

Type Description
DragPreview DragPreview object. It provides the API for setting the preview style. It does not work in the OnDrop and OnDragEnd callbacks.

Example

For details, see animate.

DragPreview11+

Implements a DragPreview object. This API does not work in the OnDrop and OnDragEnd callbacks.

System capability: SystemCapability.ArkUI.ArkUI.Full

setForegroundColor11+

setForegroundColor(color: ResourceColor): void

Sets the mask color of the drag preview. This API does not work in the OnDrop and OnDragEnd callbacks.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
color ResourceColor Yes Mask color of the drag preview.

Example

For details, see animate.

animate11+

animate(options: AnimationOptions, handler: () => void): void

Applies an animation to the background mask color changes. This API does not work in the OnDrop and OnDragEnd callbacks.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
options AnimationOptions Yes Animation settings.
handler () => void Yes Callback used to change attributes such as the background mask color.

Example

  1. In the EntryAbility.ets file, obtain the UI context and save it to LocalStorage.
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
import { UIContext } from '@ohos.arkui.UIContext';

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 {
  hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

  windowStage.loadContent('pages/Index', (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) {
        hilog.error(0x0000, 'Failed to abtain the main window. Cause:' + err.message, '');
        return;
      }
      let windowClass: window.Window = data;
      uiContext = windowClass.getUIContext();
      this.storage.setOrCreate<UIContext>('uiContext', uiContext);
    })
  });
}
}
  1. In the Index.ets file, call LocalStorage.getShared() to obtain the UI context and then use the DragController object obtained to perform subsequent operations.

import UDC from '@ohos.data.unifiedDataChannel';
import hilog from '@ohos.hilog';
import dragController from "@ohos.arkui.dragController";
import image from '@ohos.multimedia.image';
import curves from '@ohos.curves';
import { BusinessError } from '@ohos.base';
import { UIContext } from '@ohos.arkui.UIContext';


let storages = LocalStorage.getShared();

@Entry(storages)
@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('Drag Here').onDragEnter(() => {
        try {
          let uiContext: UIContext = storages.get<UIContext>('uiContext') as UIContext;
          let previewObj: dragController.DragPreview = uiContext.getDragController().getDragPreview();
          let foregroundColor: ResourceColor = Color.Green;

          let previewAnimation: dragController.AnimationOptions = {
            curve: curves.cubicBezierCurve(0.2,0,0,1),
          }
          previewObj.animate(previewAnimation, () => {
            previewObj.setForegroundColor(foregroundColor);
          });
        } catch (error) {
          let msg = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          hilog.error(0x0000, `show error code is ${code}, message is ${msg}`, '');
        }
    })
    .onDrop(() => {

    })
    Button ('Drag').onTouch ((event?:TouchEvent) => {
      if(event){
        if (event.type == TouchType.Down) {
          let text = new UDC.Text()
          let unifiedData = new UDC.UnifiedData(text)
          let dragInfo: dragController.DragInfo = {
            pointerId: 0,
            data: unifiedData,
            extraParams: ''
          }
            class tmp{
              event:DragEvent|undefined = undefined
              extraParams:string = ''
            }
            let eve:tmp = new tmp()
            dragController.executeDrag(() => {
              this.DraggingBuilder()
            }, dragInfo, (err , eve) => {
              hilog.info(0x0000, `ljx ${JSON.stringify(err)}`, '')
              if (eve && eve.event) {
                if (eve.event.getResult() == DragResult.DRAG_SUCCESSFUL) {
                  hilog.info(0x0000, 'success', '');
                } else if (eve.event.getResult() == DragResult.DRAG_FAILED) {
                  hilog.info(0x0000, 'failed', '');
                }
              }
          })
        }
      }
    }).margin({top:100})
  }
  .width('100%')
  .height('100%')
}
}