拖拽事件
ArkUI开发框架针对拖拽事件提供了NODE_ON_PRE_DRAG,NODE_ON_DRAG_START,NODE_ON_DROP,NODE_ON_DRAG_ENTER,NODE_ON_DRAG_MOVE,NODE_ON_DRAG_LEAVE,NODE_ON_DRAG_END等组件事件,当拖拽在不同的阶段时会触发对应的组件事件,完成对应的数据处理操作,实现期望的拖拽交互能力。
通用拖拽
ArkUI提供了使用C和C++开发拖拽功能的能力,开发者可调用C API实现拖拽功能。以下以Image组件为例,详细介绍C API实现拖拽功能的基本步骤,以及在开发过程中需要注意的事项。
-
组件拖拽设置。
获取Node-API,创建节点等操作均需通过Node-API完成。
ArkUI_NativeNodeAPI_1 *nativeNodeAPI = nullptr; OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nativeNodeAPI); nodeAPI = nativeNodeAPI;创建Image节点,并设置draggable和其它相关属性。
dragImage2 = nodeAPI->createNode(ARKUI_NODE_IMAGE); SetId(dragImage2, "dragImage"); SetCommonAttribute(dragImage2, 140.0f, 140.0f, 0xFFFFFFFF, 5.0f); // 图片src/main/ets/resources/seagull.png需要替换为开发者所需的资源文件 SetImageSrc(dragImage2, "/resources/seagull.png"); OH_ArkUI_SetNodeDraggable(dragImage2, true); nodeAPI->registerNodeEvent(dragImage2, NODE_ON_DRAG_START, 1, nullptr);#define DEFAULT_WIDTH 200.0 void SetWidth(ArkUI_NodeHandle &node, float width = DEFAULT_WIDTH) { if (!nodeAPI) { return; } ArkUI_NumberValue widthValue[] = {width}; ArkUI_AttributeItem widthItem = {widthValue, 1}; nodeAPI->setAttribute(node, NODE_WIDTH, &widthItem); } #define DEFAULT_HEIGHT 200.0 void SetHeight(ArkUI_NodeHandle &node, float height = DEFAULT_HEIGHT) { if (!nodeAPI) { return; } ArkUI_NumberValue heightValue[] = {height}; ArkUI_AttributeItem heightItem = {heightValue, 1}; nodeAPI->setAttribute(node, NODE_HEIGHT, &heightItem); } #define DEFAULT_BG_COLOR 0xFFFFFFFF void SetBackgroundColor(ArkUI_NodeHandle &node, uint32_t color = DEFAULT_BG_COLOR) { if (!nodeAPI) { return; } ArkUI_NumberValue colorValue[] = {{.u32 = color}}; ArkUI_AttributeItem colorItem = {colorValue, 1}; nodeAPI->setAttribute(node, NODE_BACKGROUND_COLOR, &colorItem); } #define DEFAULT_MARGIN 5.0 void SetMargin(ArkUI_NodeHandle &node, float margin = DEFAULT_MARGIN) { if (!nodeAPI) { return; } ArkUI_NumberValue marginValue[] = {margin}; ArkUI_AttributeItem marginItem = {marginValue, 1}; nodeAPI->setAttribute(node, NODE_MARGIN, &marginItem); } void SetButtonLabel(ArkUI_NodeHandle &node, const char *label) { if (!nodeAPI) { return; } ArkUI_AttributeItem NODE_Button_SRC_Item = {.string = label}; nodeAPI->setAttribute(node, NODE_BUTTON_LABEL, &NODE_Button_SRC_Item); } void SetId(ArkUI_NodeHandle &node, const char *id) { if (!nodeAPI) { return; } ArkUI_AttributeItem idItem = {.string = id}; nodeAPI->setAttribute(node, NODE_ID, &idItem); } #define DEFAULT_BORDER_WIDTH 0.0 void SetBorderWidth(ArkUI_NodeHandle &node, float width = DEFAULT_BORDER_WIDTH) { if (!nodeAPI) { return; } ArkUI_NumberValue borderWidthValue[] = {width}; ArkUI_AttributeItem borderWidthItem = {borderWidthValue, 1}; nodeAPI->setAttribute(node, NODE_BORDER_WIDTH, &borderWidthItem); } #define DEFAULT_BORDER_COLOR 0xFF000000 void SetBorderColor(ArkUI_NodeHandle &node, uint32_t color = DEFAULT_BORDER_COLOR) { if (!nodeAPI) { return; } ArkUI_NumberValue borderColorValue[] = {{.u32 = color}}; ArkUI_AttributeItem borderColorItem = {borderColorValue, 1}; nodeAPI->setAttribute(node, NODE_BORDER_COLOR, &borderColorItem); } void SetCommonAttribute(ArkUI_NodeHandle &node, float width = DEFAULT_WIDTH, float height = DEFAULT_HEIGHT, unsigned int color = DEFAULT_BG_COLOR, float margin = DEFAULT_MARGIN) { SetWidth(node, width); SetHeight(node, height); SetBackgroundColor(node, color); SetMargin(node, margin); SetBorderWidth(node, DEFAULT_BORDER_WIDTH); SetBorderColor(node); }void SetImageSrc(ArkUI_NodeHandle &node, const char *src) { if (!nodeAPI) { return; } ArkUI_AttributeItem imageSrcItem = {.string = src}; nodeAPI->setAttribute(node, NODE_IMAGE_SRC, &imageSrcItem); } -
自定义拖拽预览和背板图。
创建pixelMap,设置pixelMap的宽高等各项属性。设置Image节点的dragPreviewOption,可用于设置跟手图的圆角、角标等。
// 创建pixelMap uint8_t data[960000]; size_t dataSize = 960000; for (int i = 0; i < dataSize; i++) { data[i] = i + 1; } // 创建参数结构体实例,并设置参数 OH_Pixelmap_InitializationOptions *createOpts; OH_PixelmapInitializationOptions_Create(&createOpts); OH_PixelmapInitializationOptions_SetWidth(createOpts, 200U); OH_PixelmapInitializationOptions_SetHeight(createOpts, 200U); OH_PixelmapInitializationOptions_SetPixelFormat(createOpts, PIXEL_FORMAT_BGRA_8888); OH_PixelmapInitializationOptions_SetAlphaType(createOpts, PIXELMAP_ALPHA_TYPE_UNKNOWN); // 设置自定义跟手图 OH_PixelmapNative *pixelmap = nullptr; OH_PixelmapNative_CreatePixelmap(data, dataSize, createOpts, &pixelmap); OH_PixelmapNative_Opacity(pixelmap, 0.1f); OH_ArkUI_SetNodeDragPreview(node, pixelmap); // 设置跟手图选项 auto *previewOptionsText = OH_ArkUI_CreateDragPreviewOption(); OH_ArkUI_DragPreviewOption_SetScaleMode(previewOptionsText, ARKUI_DRAG_PREVIEW_SCALE_DISABLED); OH_ArkUI_DragPreviewOption_SetNumberBadgeEnabled(previewOptionsText, true); OH_ArkUI_DragPreviewOption_SetBadgeNumber(previewOptionsText, 10U); OH_ArkUI_DragPreviewOption_SetDefaultShadowEnabled(previewOptionsText, true); OH_ArkUI_DragPreviewOption_SetDefaultRadiusEnabled(previewOptionsText, true); int returnValue = OH_ArkUI_DragPreviewOption_SetDefaultAnimationBeforeLiftingEnabled(previewOptionsText, true); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "Manager", "dragTest DragPreviewOption_SetDefaultAnimationBeforeLiftingEnabled returnValue = %{public}d", returnValue); OH_ArkUI_SetNodeDragPreviewOption(node, previewOptionsText); -
设置相关事件。
C API的事件通过统一的回调来接收,当收到事件时通过eventType进行区分。
nodeAPI->addNodeEventReceiver(dragNode, [](ArkUI_NodeEvent *event) { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "RegisterNodeEventFirstReceiver called"); auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); auto preDragStatus = OH_ArkUI_NodeEvent_GetPreDragStatus(event); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "eventType = %{public}d, preDragStatus = %{public}d", eventType, preDragStatus); auto *dragEvent = OH_ArkUI_NodeEvent_GetDragEvent(event); switch (eventType) { case NODE_ON_PRE_DRAG: OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_PRE_DRAG Event Receive"); break; case NODE_ON_CLICK: OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_CLICK Event Receive"); break; case NODE_ON_DROP: OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_DROP Event Receive"); break; case NODE_ON_DRAG_ENTER: OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_DRAG_ENTER Event Receive"); break; case NODE_ON_DRAG_MOVE: OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_DRAG_MOVE Event Receive"); break; case NODE_ON_DRAG_LEAVE: OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_DRAG_LEAVE Event Receive"); break; case NODE_ON_DRAG_START: { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_DRAG_START Event Receive"); // ... break; } case NODE_ON_DRAG_END: { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_DRAG_END Event Receive"); // ... break; } default: OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "UNKNOWN Event Receive"); break; } }); -
处理NODE_ON_DRAG_START事件。
在NODE_ON_DRAG_START事件中,应用可以执行起拖阶段所需的操作,通常涉及处理起拖过程的数据。例如,创建UdmfRecord,将用于拖拽图片所需的数据 imageUri以fileUri类型添加到UdmfRecord中,接着将UdmfRecord设置到udmfData中,最后将UdmfData设置到DragEvent中。
void SetImageData(ArkUI_DragEvent* dragEvent) { int returnValue; OH_UdmfRecord *record = OH_UdmfRecord_Create(); OH_UdsFileUri *imageValue = OH_UdsFileUri_Create(); // 图片src/main/ets/resources/seagull.png需要替换为开发者所需的资源文件 returnValue = OH_UdsFileUri_SetFileUri(imageValue, "/resources/seagull.png"); returnValue = OH_UdmfRecord_AddFileUri(record, imageValue); OH_UdmfData *data = OH_UdmfData_Create(); returnValue = OH_UdmfData_AddRecord(data, record); returnValue = OH_ArkUI_DragEvent_SetData(dragEvent, data); } // ··· case NODE_ON_DRAG_START: { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_DRAG_START EventReceiver"); SetImageData(dragEvent); break; } -
处理NODE_ON_DROP事件。
在NODE_ON_DROP事件中,应用可以执行与落入阶段相关的操作,通常需要获取拖拽过程中传递的数据。例如,引用<database/udmf/udmf_meta.h>头文件,获取udmfData,判断是否存在所需的数据类型,从UdmfRecord中提取相应的数据,最后销毁指针。
void GetDragData(ArkUI_DragEvent* dragEvent) { // 获取UDMF data int returnValue; // 创建OH_UdmfData对象 OH_UdmfData *data = OH_UdmfData_Create(); returnValue = OH_ArkUI_DragEvent_GetUdmfData(dragEvent, data); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_DragEvent_GetUdmfData returnValue = %{public}d", returnValue); // 判断OH_UdmfData是否有对应的类型 bool resultUdmf = OH_UdmfData_HasType(data, UDMF_META_GENERAL_FILE); if (resultUdmf) { // 获取OH_UdmfData的记录 unsigned int recordsCount = 0; OH_UdmfRecord **records = OH_UdmfData_GetRecords(data, &recordsCount); // 获取records中的元素 int returnStatus; for (int i = 0; i < recordsCount; i++) { // 从OH_UdmfRecord中获取文件类型数据 OH_UdsFileUri *imageValue = OH_UdsFileUri_Create(); returnStatus = OH_UdmfRecord_GetFileUri(records[i], imageValue); const char *fileUri = OH_UdsFileUri_GetFileUri(imageValue); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "dragTest OH_UdmfRecord_GetPlainText " "returnStatus= %{public}d " "fileUri= %{public}s", returnStatus, fileUri); // 使用结束后销毁指针 OH_UdsFileUri_Destroy(imageValue); } if (recordsCount != 0) { OH_ArkUI_DragEvent_SetDragResult(dragEvent, ARKUI_DRAG_RESULT_SUCCESSFUL); ArkUI_DropOperation option; OH_ArkUI_DragEvent_GetDropOperation(dragEvent, &option); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_DragEvent_GetDropOperation returnValue = %{public}d", option); } } else { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_UdmfData_HasType not contain UDMF_META_GENERAL_FILE"); } int32_t count; OH_ArkUI_DragEvent_GetDataTypeCount(dragEvent, &count); if (count <= 0 || count >= 128U) { return; } char **eventTypeArray = new char *[count]; for (int i = 0; i < count; i++) { eventTypeArray[i] = new char[128U]; } OH_ArkUI_DragEvent_GetDataTypes(dragEvent, eventTypeArray, count, 128U); for (int i = 0; i < count; i++) { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_DragEvent_GetDataTypes returnValue = %{public}s", eventTypeArray[i]); } } // ... case NODE_ON_DROP: { OH_ArkUI_DragEvent_SetSuggestedDropOperation(dragEvent, ARKUI_DROP_OPERATION_COPY); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_DROP EventReceiver"); GetDragData(dragEvent); break; }
DragAction主动发起拖拽
除了通用拖拽以外,ArkUI还提供了使用C API实现主动发起拖拽的能力。以下以文本拖拽为例,详细介绍C-API实现主动发起拖拽的基本步骤,以及在开发过程中需要注意的事项。
-
节点注册事件。
创建Button节点,设置按钮相关属性,同时需要注册NODE_ON_TOUCH_INTERCEPT事件。
// buttonTouch作为targetId,用于区分不同target的事件。 enum { BUTTON_TOUCH = 1 }; dragButton = nodeAPI->createNode(ARKUI_NODE_BUTTON); SetId(dragButton, "dragBt3"); SetCommonAttribute(dragButton, 80.0f, 50.0f, 0xFFFF0000, 20.0f); SetButtonLabel(dragButton, "拖起"); nodeAPI->registerNodeEvent(dragButton, NODE_ON_TOUCH_INTERCEPT, BUTTON_TOUCH, nullptr);#define DEFAULT_WIDTH 200.0 void SetWidth(ArkUI_NodeHandle &node, float width = DEFAULT_WIDTH) { if (!nodeAPI) { return; } ArkUI_NumberValue widthValue[] = {width}; ArkUI_AttributeItem widthItem = {widthValue, 1}; nodeAPI->setAttribute(node, NODE_WIDTH, &widthItem); } #define DEFAULT_HEIGHT 200.0 void SetHeight(ArkUI_NodeHandle &node, float height = DEFAULT_HEIGHT) { if (!nodeAPI) { return; } ArkUI_NumberValue heightValue[] = {height}; ArkUI_AttributeItem heightItem = {heightValue, 1}; nodeAPI->setAttribute(node, NODE_HEIGHT, &heightItem); } #define DEFAULT_BG_COLOR 0xFFFFFFFF void SetBackgroundColor(ArkUI_NodeHandle &node, uint32_t color = DEFAULT_BG_COLOR) { if (!nodeAPI) { return; } ArkUI_NumberValue colorValue[] = {{.u32 = color}}; ArkUI_AttributeItem colorItem = {colorValue, 1}; nodeAPI->setAttribute(node, NODE_BACKGROUND_COLOR, &colorItem); } #define DEFAULT_MARGIN 5.0 void SetMargin(ArkUI_NodeHandle &node, float margin = DEFAULT_MARGIN) { if (!nodeAPI) { return; } ArkUI_NumberValue marginValue[] = {margin}; ArkUI_AttributeItem marginItem = {marginValue, 1}; nodeAPI->setAttribute(node, NODE_MARGIN, &marginItem); } void SetButtonLabel(ArkUI_NodeHandle &node, const char *label) { if (!nodeAPI) { return; } ArkUI_AttributeItem NODE_Button_SRC_Item = {.string = label}; nodeAPI->setAttribute(node, NODE_BUTTON_LABEL, &NODE_Button_SRC_Item); } void SetId(ArkUI_NodeHandle &node, const char *id) { if (!nodeAPI) { return; } ArkUI_AttributeItem idItem = {.string = id}; nodeAPI->setAttribute(node, NODE_ID, &idItem); } #define DEFAULT_BORDER_WIDTH 0.0 void SetBorderWidth(ArkUI_NodeHandle &node, float width = DEFAULT_BORDER_WIDTH) { if (!nodeAPI) { return; } ArkUI_NumberValue borderWidthValue[] = {width}; ArkUI_AttributeItem borderWidthItem = {borderWidthValue, 1}; nodeAPI->setAttribute(node, NODE_BORDER_WIDTH, &borderWidthItem); } #define DEFAULT_BORDER_COLOR 0xFF000000 void SetBorderColor(ArkUI_NodeHandle &node, uint32_t color = DEFAULT_BORDER_COLOR) { if (!nodeAPI) { return; } ArkUI_NumberValue borderColorValue[] = {{.u32 = color}}; ArkUI_AttributeItem borderColorItem = {borderColorValue, 1}; nodeAPI->setAttribute(node, NODE_BORDER_COLOR, &borderColorItem); } void SetCommonAttribute(ArkUI_NodeHandle &node, float width = DEFAULT_WIDTH, float height = DEFAULT_HEIGHT, unsigned int color = DEFAULT_BG_COLOR, float margin = DEFAULT_MARGIN) { SetWidth(node, width); SetHeight(node, height); SetBackgroundColor(node, color); SetMargin(node, margin); SetBorderWidth(node, DEFAULT_BORDER_WIDTH); SetBorderColor(node); } -
接收NODE_ON_TOUCH_INTERCEPT事件。
DragAction主动发起拖拽需通过事件触发,在NODE_ON_TOUCH_INTERCEPT事件中执行发起拖拽所需的操作,通过targetId区分不同按钮触发的事件。
nodeAPI->addNodeEventReceiver(dragButton, [](ArkUI_NodeEvent *event) { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "RegisterNodeEventForthReceiver called"); auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); auto preDragStatus = OH_ArkUI_NodeEvent_GetPreDragStatus(event); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "eventType = %{public}d, preDragStatus = %{public}d", eventType, preDragStatus); auto *dragEvent = OH_ArkUI_NodeEvent_GetDragEvent(event); switch (eventType) { case NODE_ON_TOUCH_INTERCEPT: { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_TOUCH_INTERCEPT EventReceiver"); // ... break; } default: { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "UNKNOWN EventReceiver"); break; } } }); -
起拖阶段设置。
在NODE_ON_TOUCH_INTERCEPT事件中,需要对DragAction进行相关设置。为了主动发起拖拽,需要创建pixelMap,设置dragPreviewOption和跟手点,并将拖拽过程中的文本数据设置到DragAction中。
case NODE_ON_TOUCH_INTERCEPT: { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_TOUCH_INTERCEPT EventReceiver"); // 创建DragAction action = OH_ArkUI_CreateDragActionWithNode(dragButton); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_CreateDragActionWithNode returnValue = %{public}p", action); // 设置pixelMap std::vector<OH_PixelmapNative *> pixelVector; SetPixelMap(pixelVector); // 设置DragPreviewOption SetDragPreviewOption(); // 设置pointerId、touchPoint PrintDragActionInfos(); // 设置unifiedData SetDragActionData(); // startDrag int returnValue = OH_ArkUI_StartDrag(action); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_StartDrag returnValue = %{public}d", returnValue); OH_ArkUI_DragAction_Dispose(action); break; } // ... void SetDragActionData() { // 创建OH_UdmfRecord对象 OH_UdmfRecord *record = OH_UdmfRecord_Create(); // 向OH_UdmfRecord中添加纯文本类型数据 OH_UdsPlainText *plainText = OH_UdsPlainText_Create(); int returnStatus; OH_UdsPlainText_SetAbstract(plainText, "this is plainText Abstract example"); OH_UdsPlainText_SetContent(plainText, "this is plainText Content example"); returnStatus = OH_UdmfRecord_AddPlainText(record, plainText); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "dragTest OH_UdmfRecord_AddPlainText returnStatus = %{public}d", returnStatus); // 创建OH_UdmfData对象 OH_UdmfData *data = OH_UdmfData_Create(); // 向OH_UdmfData中添加OH_UdmfRecord returnStatus = OH_UdmfData_AddRecord(data, record); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "dragTest OH_UdmfData_AddRecord returnStatus = %{public}d", returnStatus); int returnValue = OH_ArkUI_DragAction_SetData(action, data); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_DragAction_SetData returnValue = %{public}d", returnValue); // 注册拖拽状态监听回调 OH_ArkUI_DragAction_RegisterStatusListener(action, data, &DragStatusListener); }void SetPixelMap(std::vector<OH_PixelmapNative *> &pixelVector) { uint8_t data[960000]; size_t dataSize = 960000; for (int i = 0; i < dataSize; i++) { data[i] = i + 1; } // 创建参数结构体实例,并设置参数 OH_Pixelmap_InitializationOptions *createOpts; OH_PixelmapInitializationOptions_Create(&createOpts); OH_PixelmapInitializationOptions_SetWidth(createOpts, 200U); OH_PixelmapInitializationOptions_SetHeight(createOpts, 300U); OH_PixelmapInitializationOptions_SetPixelFormat(createOpts, PIXEL_FORMAT_BGRA_8888); OH_PixelmapInitializationOptions_SetAlphaType(createOpts, PIXELMAP_ALPHA_TYPE_UNKNOWN); // 创建Pixelmap实例 OH_PixelmapNative *pixelmap = nullptr; OH_PixelmapNative_CreatePixelmap(data, dataSize, createOpts, &pixelmap); OH_PixelmapNative_Flip(pixelmap, true, true); pixelVector.push_back(pixelmap); int returnValue = OH_ArkUI_DragAction_SetPixelMaps(action, pixelVector.data(), pixelVector.size()); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_DragAction_SetPixelMaps returnValue = %{public}d", returnValue); } void SetDragPreviewOption() { auto *previewOptions = OH_ArkUI_CreateDragPreviewOption(); OH_ArkUI_DragPreviewOption_SetScaleMode(previewOptions, ArkUI_DragPreviewScaleMode::ARKUI_DRAG_PREVIEW_SCALE_DISABLED); OH_ArkUI_DragPreviewOption_SetDefaultShadowEnabled(previewOptions, true); OH_ArkUI_DragPreviewOption_SetDefaultRadiusEnabled(previewOptions, true); int returnValue = OH_ArkUI_DragAction_SetDragPreviewOption(action, previewOptions); OH_ArkUI_DragPreviewOption_Dispose(previewOptions); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_DragAction_SetDragPreviewOption returnValue = %{public}d", returnValue); } void PrintDragActionInfos() { // 设置pointerId int returnValue = OH_ArkUI_DragAction_SetPointerId(action, 0); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_DragAction_SetPointerId returnValue = %{public}d", returnValue); // 设置touchPoint returnValue = OH_ArkUI_DragAction_SetTouchPointX(action, 200.0f); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_DragAction_SetTouchPointX returnValue = %{public}d", returnValue); returnValue = OH_ArkUI_DragAction_SetTouchPointY(action, 200.0f); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_DragAction_SetTouchPointY returnValue = %{public}d", returnValue); } -
处理NODE_ON_DROP事件。
在NODE_ON_DROP事件中,应用可以执行与落入阶段相关的操作。通常情况下,需要从DragEvent中获取拖拽过程中传递的数据,DragAction中的拖拽数据也需要通过DragEvent获取。
case NODE_ON_DROP: { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "NODE_ON_DROP EventReceiver"); GetUdmfDataText(dragEvent); OH_ArkUI_DragAction_UnregisterStatusListener(action); break; } // ... void GetUdmfDataText(ArkUI_DragEvent* dragEvent) { // 获取UDMF data int returnValue; // 创建OH_UdmfData对象 OH_UdmfData *data = OH_UdmfData_Create(); returnValue = OH_ArkUI_DragEvent_GetUdmfData(dragEvent, data); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_ArkUI_DragEvent_GetUdmfData returnValue = %{public}d", returnValue); // 判断OH_UdmfData是否有对应的类型 bool resultUdmf = OH_UdmfData_HasType(data, UDMF_META_PLAIN_TEXT); if (resultUdmf) { // 获取OH_UdmfData的记录 unsigned int recordsCount = 0; OH_UdmfRecord **records = OH_UdmfData_GetRecords(data, &recordsCount); // 获取records中的元素 int returnStatus; for (int i = 0; i < recordsCount; i++) { // 从OH_UdmfRecord中获取纯文本类型数据 OH_UdsPlainText *plainTextValue = OH_UdsPlainText_Create(); returnStatus = OH_UdmfRecord_GetPlainText(records[i], plainTextValue); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "dragTest OH_UdmfRecord_GetPlainText " "returnStatus= %{public}d", returnStatus); auto getAbstract = OH_UdsPlainText_GetAbstract(plainTextValue); auto getContent = OH_UdsPlainText_GetContent(plainTextValue); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_UdsPlainText_GetAbstract = " "%{public}s, OH_UdsPlainText_GetContent = " "%{public}s", getAbstract, getContent); // 使用结束后销毁指针 OH_UdsPlainText_Destroy(plainTextValue); } } else { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00U, "dragTest", "OH_UdmfData_HasType not contain UDMF_META_PLAIN_TEXT"); } OH_UdmfData_Destroy(data); }