绑定手势事件
======

ArkUI开发框架在NDK接口主要提供点击手势、滑动手势、快滑手势、长按手势、捏合手势和旋转手势，通过给指定的组件绑定不同的手势并设置相应的回调，实现期望的手势交互能力。

下面通过一个简单的示例来介绍如何实现手势绑定。

1.  创建一个Column节点，用于绑定手势。
    
    // 创建Column节点
    auto column = nodeAPI->createNode(ARKUI\_NODE\_COLUMN);
    // 设置背景色
    ArkUI\_NumberValue value\[\] = {{.u32 = 0xff112233}};
    ArkUI\_AttributeItem item = {value, 1};
    nodeAPI->setAttribute(column, NODE\_BACKGROUND\_COLOR, &item);
    // 设置宽度
    ArkUI\_NumberValue widthValue\[\] = {{400}};
    ArkUI\_AttributeItem width = {widthValue, 1};
    nodeAPI->setAttribute(column, NODE\_WIDTH, &width);
    // 设置高度
    ArkUI\_NumberValue heightValue\[\] = {{400}};
    ArkUI\_AttributeItem height = {heightValue, 1};
    nodeAPI->setAttribute(column, NODE\_HEIGHT, &height);
    
2.  创建一个单指长按1秒并持续响应的长按手势。
    
    // 获取手势Native接口集合
    auto gestureApi = reinterpret\_cast<ArkUI\_NativeGestureAPI\_1 \*>(
        OH\_ArkUI\_QueryModuleInterfaceByName(ARKUI\_NATIVE\_GESTURE, "ArkUI\_NativeGestureAPI\_1"));
    // 创建长按手势
    // DURATION\_NUM\_1000 = 1000
    auto longPressGesture = gestureApi->createLongPressGesture(1, true, DURATION\_NUM\_1000);
    
3.  将创建的手势和步骤一中创建的Column节点绑定。
    
    auto onActionCallBack = \[\](ArkUI\_GestureEvent \*event, void \*extraParam) {
        // 回调内容
        // ···
    };
    
    // 将手势设置到组件上
    gestureApi->setGestureEventTarget(
        longPressGesture, GESTURE\_EVENT\_ACTION\_ACCEPT | GESTURE\_EVENT\_ACTION\_UPDATE | GESTURE\_EVENT\_ACTION\_END, column,
        onActionCallBack);
    
    gestureApi->addGestureToNode(column, longPressGesture, PARALLEL, NORMAL\_GESTURE\_MASK);
    

#### 单一手势

通过上文的示例已经了解了如何将手势绑定在节点上，接下来将分别介绍不同手势的创建方法。

*   点击手势
    
    通过给组件绑定点击手势可在组件被点击时触发此回调，可指定触发回调需要的点击次数和手指个数。
    
    // 获取手势Native接口集合
    auto gestureApi = reinterpret\_cast<ArkUI\_NativeGestureAPI\_1 \*>(
        OH\_ArkUI\_QueryModuleInterfaceByName(ARKUI\_NATIVE\_GESTURE, "ArkUI\_NativeGestureAPI\_1"));
    // 创建点击手势
    auto tapGesture = gestureApi->createTapGesture(1, 1);
    
*   滑动手势
    
    通过给组件绑定滑动手势可在用户滑动组件时触发回调，可指定触发回调需要的手指个数、滑动方向、滑动距离。单位为px。
    
    // 获取手势Native接口集合
    auto gestureApi = reinterpret\_cast<ArkUI\_NativeGestureAPI\_1 \*>(
        OH\_ArkUI\_QueryModuleInterfaceByName(ARKUI\_NATIVE\_GESTURE, "ArkUI\_NativeGestureAPI\_1"));
    // 创建滑动手势
    auto panGesture = gestureApi->createPanGesture(1, GESTURE\_DIRECTION\_ALL, 1);
    
*   长按手势
    
    通过给组件绑定长按手势可在用户长按组件时触发回调，可指定触发回调需要的手指个数、长按时间（单位毫秒）、是否连续触发。
    
    // 获取手势Native接口集合
    auto gestureApi = reinterpret\_cast<ArkUI\_NativeGestureAPI\_1 \*>(
        OH\_ArkUI\_QueryModuleInterfaceByName(ARKUI\_NATIVE\_GESTURE, "ArkUI\_NativeGestureAPI\_1"));
    // 创建长按手势
    // DURATION\_NUM\_1000 = 1000
    auto longPressGesture = gestureApi->createLongPressGesture(1, true, DURATION\_NUM\_1000);
    
*   捏合手势
    
    通过给组件绑定捏合手势可在用户捏合组件时触发回调，可指定触发回调需要的手指个数（最小为2）、捏合距离（单位px）。
    
    // 获取手势Native接口集合
    auto gestureApi = reinterpret\_cast<ArkUI\_NativeGestureAPI\_1 \*>(
        OH\_ArkUI\_QueryModuleInterfaceByName(ARKUI\_NATIVE\_GESTURE, "ArkUI\_NativeGestureAPI\_1"));
    // 创建捏合手势
    // NUMBER\_2 = 2，NUMBER\_10 = 10
    auto pinchGesture = gestureApi->createPinchGesture(NUMBER\_2, NUMBER\_10);
    
*   旋转手势
    
    通过给组件绑定旋转手势可在用户旋转组件时触发回调，可指定触发回调需要的手指个数（最小为2）、旋转角度。
    
    // 获取手势Native接口集合
    auto gestureApi = reinterpret\_cast<ArkUI\_NativeGestureAPI\_1 \*>(
        OH\_ArkUI\_QueryModuleInterfaceByName(ARKUI\_NATIVE\_GESTURE, "ArkUI\_NativeGestureAPI\_1"));
    // 创建旋转手势
    // NUMBER\_2 = 2，NUMBER\_10 = 10
    auto rotationGesture = gestureApi->createRotationGesture(NUMBER\_2, NUMBER\_10);
    
*   快滑手势
    
    通过给组件绑定快滑手势可在用户快速滑动组件时触发回调，可指定触发回调需要的手指个数（最小为1）、滑动方向、滑动速度（单位px/s）。
    
    // 获取手势Native接口集合
    auto gestureApi = reinterpret\_cast<ArkUI\_NativeGestureAPI\_1 \*>(
        OH\_ArkUI\_QueryModuleInterfaceByName(ARKUI\_NATIVE\_GESTURE, "ArkUI\_NativeGestureAPI\_1"));
    // 创建快滑手势
    // SPEED\_NUM\_50 = 50
    auto swipeGesture = gestureApi->createSwipeGesture(1, GESTURE\_DIRECTION\_ALL, SPEED\_NUM\_50);
    

#### 组合手势

可以将多个不同类型的手势组合在一起，形成一个手势组，这个手势组可以作为一个识别整体，达到对用户多个不同类型手势序列的识别目的。

通过设置[ArkUI\_GroupGestureMode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-gesture-h#arkui_groupgesturemode)来指定这个手势组的识别模式，即组内的手势之间的关系，包含顺序识别SEQUENTIAL\_GROUP，并行识别PARALLEL\_GROUP，互斥识别EXCLUSIVE\_GROUP。

#### \[h2\]顺序识别

顺序识别组合手势对应的ArkUI\_GroupGestureMode为SEQUENTIAL\_GROUP。顺序识别组合手势将按照手势的注册顺序识别手势，直到所有的手势识别成功。当顺序识别组合手势中有一个手势识别失败时，后续手势识别均失败。顺序识别手势组仅有最后一个手势可以响应[GESTURE\_EVENT\_ACTION\_END](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-gesture-h#arkui_gestureeventactiontype)。

以顺序识别长按和滑动手势为例：

// LongPressAndSwipeGesture.h
#include <arkui/native\_animate.h>
#include <arkui/native\_gesture.h>
#include <arkui/native\_interface.h>
#include <arkui/native\_node.h>
#include <arkui/native\_type.h>
#include <arkui/native\_node\_napi.h>
#include <hilog/log.h>
#include "Common.h"
#include "Function.h"
// ...
ArkUI\_NodeHandle LongPressAndSwipeGesture()
{
    auto column = nodeAPI->createNode(ARKUI\_NODE\_COLUMN);

    // 创建节点
    ArkUI\_NumberValue value\[\] = {{.u32 = 0xff112233}};
    ArkUI\_AttributeItem item = {value, ITEM\_SIZE\_ONE};
    nodeAPI->setAttribute(column, NODE\_BACKGROUND\_COLOR, &item);
    ArkUI\_NumberValue widthValue\[\] = {{WIDTH\_SIZE}};
    ArkUI\_AttributeItem width = {widthValue, ITEM\_SIZE\_ONE};
    nodeAPI->setAttribute(column, NODE\_WIDTH, &width);
    ArkUI\_NumberValue heightValue\[\] = {{HEIGHT\_SIZE}};
    ArkUI\_AttributeItem height = {heightValue, ITEM\_SIZE\_ONE};
    nodeAPI->setAttribute(column, NODE\_HEIGHT, &height);

    // 判断是否支持创建手势
    auto gestureApi = reinterpret\_cast<ArkUI\_NativeGestureAPI\_1 \*>(
        OH\_ArkUI\_QueryModuleInterfaceByName(ARKUI\_NATIVE\_GESTURE, "ArkUI\_NativeGestureAPI\_1"));
    if (gestureApi->createGroupGesture) {
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, createGroupGesture api exist");
    } else {
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, createGroupGesture api not exist");
    }
    auto groupGesture = gestureApi->createGroupGesture(ArkUI\_GroupGestureMode::SEQUENTIAL\_GROUP);

    // 创建长按手势
    auto longPressGesture = gestureApi->createLongPressGesture(FINGERS\_NUM, true, DURATION\_NUM);
    if (gestureApi->getGestureType) {
        ArkUI\_GestureRecognizerType type = gestureApi->getGestureType(longPressGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog longPressGesture,"
                     "ArkUI\_GestureRecognizerType%{public}d", type);
    }
    // 给长按手势绑定回调
    auto onActionCallBackPanLongPress = \[\](ArkUI\_GestureEvent \*event, void \*extraParam) {
        ArkUI\_GestureEventActionType actionType = OH\_ArkUI\_GestureEvent\_GetActionType(event);

        float velocity = OH\_ArkUI\_PanGesture\_GetVelocity(event);
        float velocityX = OH\_ArkUI\_PanGesture\_GetVelocityX(event);
        float velocityY = OH\_ArkUI\_PanGesture\_GetVelocityY(event);
        float offsetX = OH\_ArkUI\_PanGesture\_GetOffsetX(event);
        float offsetY = OH\_ArkUI\_PanGesture\_GetOffsetY(event);
        float scale = OH\_ArkUI\_PinchGesture\_GetScale(event);
        float centerX = OH\_ArkUI\_PinchGesture\_GetCenterX(event);
        float centerY = OH\_ArkUI\_PinchGesture\_GetCenterY(event);
        float angle = OH\_ArkUI\_SwipeGesture\_GetAngle(event);
        float velocityS = OH\_ArkUI\_SwipeGesture\_GetVelocity(event);
        float angleR = OH\_ArkUI\_RotationGesture\_GetAngle(event);
        float repeat = OH\_ArkUI\_LongPress\_GetRepeatCount(event);

        OH\_LOG\_Print(
            LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
            "NdkAddInteractionEvent\_GestureSampleLog,longPressGesturecallback actionType:%{public}d,"
            "velocity%{public}f,velocityX%{public}f;"
            "velocityY%{public}f,offsetX%{public}f,offsetY%{public}f,scale%{public}fcenterX"
            "%{public}fcenterY"
            "%{public}fangle%{public}fvelocityS%{public}fangleR%{public}frepeat%{public}f",
            actionType, velocity, velocityX, velocityY, offsetX, offsetY, scale, centerX, centerY, angle, velocityS,
            angleR, repeat);
    };
    gestureApi->setGestureEventTarget(longPressGesture,
                                      GESTURE\_EVENT\_ACTION\_ACCEPT | GESTURE\_EVENT\_ACTION\_UPDATE |
                                      GESTURE\_EVENT\_ACTION\_CANCEL, column, onActionCallBackPanLongPress);

    // 将长按手势添加到手势组
    if (gestureApi->addChildGesture) {
        gestureApi->addChildGesture(groupGesture, longPressGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, addChildGesture longPressGesture");
    }
    // 创建快滑手势 swipe
    auto swipeGesture = gestureApi->createSwipeGesture(1, GESTURE\_DIRECTION\_ALL, 100);
    if (gestureApi->getGestureType) {
        ArkUI\_GestureRecognizerType type = gestureApi->getGestureType(swipeGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, ArkUI\_GestureRecognizerType %{public}d",
                     type);
    }
    // 给快滑手势绑定回调
    auto onActionCallBack = \[\](ArkUI\_GestureEvent \*event, void \*extraParam) {
        ArkUI\_GestureEventActionType actionType = OH\_ArkUI\_GestureEvent\_GetActionType(event);

        float velocity = OH\_ArkUI\_PanGesture\_GetVelocity(event);
        float velocityX = OH\_ArkUI\_PanGesture\_GetVelocityX(event);
        float velocityY = OH\_ArkUI\_PanGesture\_GetVelocityY(event);
        float offsetX = OH\_ArkUI\_PanGesture\_GetOffsetX(event);
        float offsetY = OH\_ArkUI\_PanGesture\_GetOffsetY(event);
        float scale = OH\_ArkUI\_PinchGesture\_GetScale(event);
        float centerX = OH\_ArkUI\_PinchGesture\_GetCenterX(event);
        float centerY = OH\_ArkUI\_PinchGesture\_GetCenterY(event);
        float angle = OH\_ArkUI\_SwipeGesture\_GetAngle(event);
        float velocityS = OH\_ArkUI\_SwipeGesture\_GetVelocity(event);
        float angleR = OH\_ArkUI\_RotationGesture\_GetAngle(event);
        float repeat = OH\_ArkUI\_LongPress\_GetRepeatCount(event);
        
        // 通过日志查看
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, swipeGesture "
                     "callback actionType: %{public}d, velocity %{public}f,velocityX "
                     "%{public}f; "
                     "velocityY %{public}f, offsetX %{public}f, offsetY %{public}f, scale %{public}fcenterX "
                     "%{public}f centerY"
                     " %{public}f angle %{public}f velocityS %{public}f angleR %{public}f repeat %{public}f",
                     actionType, velocity, velocityX, velocityY, offsetX, offsetY, scale, centerX, centerY, angle,
                     velocityS, angleR, repeat);

        ArkUI\_NumberValue value\[\] = {{.f32 = 0}, {.f32 = 0}, {.f32 = 0}, {.f32 = angleR}, {.f32 = 0}};
        ArkUI\_AttributeItem item = {value, ITEM\_SIZE\_FIVE};
        auto column = reinterpret\_cast<ArkUI\_NodeHandle>(extraParam);
        nodeAPI->setAttribute(column, NODE\_ROTATE, &item);
    };

    gestureApi->setGestureEventTarget(
        swipeGesture, GESTURE\_EVENT\_ACTION\_ACCEPT | GESTURE\_EVENT\_ACTION\_UPDATE | GESTURE\_EVENT\_ACTION\_END, column,
        onActionCallBack);

    // 将快滑手势添加到手势组
    if (gestureApi->addChildGesture) {
        gestureApi->addChildGesture(groupGesture, swipeGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, addChildGesture swipeGesture");
    }
    // 将手势组设置到组件上
    gestureApi->addGestureToNode(column, groupGesture, PRIORITY, NORMAL\_GESTURE\_MASK);
    return column;
}

**完整示例：**

完整示例请参考[示例工程](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/NdkAddInteractionEvent)。

#### \[h2\]并行识别

并行识别组合手势对应的ArkUI\_GroupGestureMode为PARALLEL\_GROUP。并行识别组合手势中注册的手势将同时进行识别，直到所有手势识别结束。并行识别手势组合中的手势进行识别时互不影响。

以并行识别长按和快滑手势为例：

// LongPressAndFlickGesture.h
#include <arkui/native\_animate.h>
#include <arkui/native\_gesture.h>
#include <arkui/native\_interface.h>
#include <arkui/native\_node.h>
#include <arkui/native\_type.h>
#include <arkui/native\_node\_napi.h>
#include <hilog/log.h>
#include "Common.h"
#include "Function.h"
// ...

ArkUI\_NodeHandle LongPressAndFlickGesture()
{
    auto column = nodeAPI->createNode(ARKUI\_NODE\_COLUMN);

    // 创建节点
    ArkUI\_NumberValue value\[\] = {{.u32 = 0xff112233}};
    ArkUI\_AttributeItem item = {value, ITEM\_SIZE\_ONE};
    nodeAPI->setAttribute(column, NODE\_BACKGROUND\_COLOR, &item);
    ArkUI\_NumberValue widthValue\[\] = {{WIDTH\_SIZE}};
    ArkUI\_AttributeItem width = {widthValue, ITEM\_SIZE\_ONE};
    nodeAPI->setAttribute(column, NODE\_WIDTH, &width);
    ArkUI\_NumberValue heightValue\[\] = {{HEIGHT\_SIZE}};
    ArkUI\_AttributeItem height = {heightValue, ITEM\_SIZE\_ONE};
    nodeAPI->setAttribute(column, NODE\_HEIGHT, &height);

    // 判断是否支持创建手势
    auto gestureApi = reinterpret\_cast<ArkUI\_NativeGestureAPI\_1 \*>(
        OH\_ArkUI\_QueryModuleInterfaceByName(ARKUI\_NATIVE\_GESTURE, "ArkUI\_NativeGestureAPI\_1"));
    if (gestureApi->createGroupGesture) {
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, createGroupGesture api exist");
    } else {
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, createGroupGesture api not exist");
    }

    // 创建手势组
    auto groupGesture = gestureApi->createGroupGesture(ArkUI\_GroupGestureMode::PARALLEL\_GROUP);

    // 创建长按手势
    auto longPressGesture = gestureApi->createLongPressGesture(FINGERS\_NUM, true, DURATION\_NUM\_500);
    if (gestureApi->getGestureType) {
        ArkUI\_GestureRecognizerType type = gestureApi->getGestureType(longPressGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog,ArkUI\_GestureRecognizerType%{public}d", type);
    }
    // 给长按手势绑定回调
    auto onActionCallBackPanLongPress = \[\](ArkUI\_GestureEvent \*event, void \*extraParam) {
        ArkUI\_GestureEventActionType actionType = OH\_ArkUI\_GestureEvent\_GetActionType(event);

        float velocity = OH\_ArkUI\_PanGesture\_GetVelocity(event);
        float velocityX = OH\_ArkUI\_PanGesture\_GetVelocityX(event);
        float velocityY = OH\_ArkUI\_PanGesture\_GetVelocityY(event);
        float offsetX = OH\_ArkUI\_PanGesture\_GetOffsetX(event);
        float offsetY = OH\_ArkUI\_PanGesture\_GetOffsetY(event);
        float scale = OH\_ArkUI\_PinchGesture\_GetScale(event);
        float centerX = OH\_ArkUI\_PinchGesture\_GetCenterX(event);
        float centerY = OH\_ArkUI\_PinchGesture\_GetCenterY(event);
        float angle = OH\_ArkUI\_SwipeGesture\_GetAngle(event);
        float velocityS = OH\_ArkUI\_SwipeGesture\_GetVelocity(event);
        float angleR = OH\_ArkUI\_RotationGesture\_GetAngle(event);
        float repeat = OH\_ArkUI\_LongPress\_GetRepeatCount(event);

        OH\_LOG\_Print(
            LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
            "NdkAddInteractionEvent\_GestureSampleLog,longPressGesturecallback actionType:%{public}d,"
            "velocity%{public}f,velocityX%{public}f;"
            "velocityY%{public}f,offsetX%{public}f,offsetY%{public}f,scale%{public}f, centerX "
            "%{public}fcenterY"
            "%{public}fangle%{public}fvelocityS%{public}fangleR%{public}frepeat%{public}f",
            actionType, velocity, velocityX, velocityY, offsetX, offsetY, scale, centerX, centerY, angle, velocityS,
            angleR, repeat);
    };
    gestureApi->setGestureEventTarget(longPressGesture,
                                      GESTURE\_EVENT\_ACTION\_ACCEPT | GESTURE\_EVENT\_ACTION\_UPDATE |
                                            GESTURE\_EVENT\_ACTION\_CANCEL,
                                      column, onActionCallBackPanLongPress);

    // 将长按手势添加到手势组
    if (gestureApi->addChildGesture) {
        gestureApi->addChildGesture(groupGesture, longPressGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, addChildGesture longPressGesture");
    }
    // 创建快滑手势 swipe
    auto swipeGesture = gestureApi->createSwipeGesture(FINGERS\_NUM, GESTURE\_DIRECTION\_ALL, DURATION\_NUM\_100);
    if (gestureApi->getGestureType) {
        ArkUI\_GestureRecognizerType type = gestureApi->getGestureType(swipeGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, ArkUI\_GestureRecognizerType %{public}d",
                     type);
    }
    // 给快滑手势绑定回调
    auto onActionCallBack = \[\](ArkUI\_GestureEvent \*event, void \*extraParam) {
        ArkUI\_GestureEventActionType actionType = OH\_ArkUI\_GestureEvent\_GetActionType(event);

        float velocity = OH\_ArkUI\_PanGesture\_GetVelocity(event);
        float velocityX = OH\_ArkUI\_PanGesture\_GetVelocityX(event);
        float velocityY = OH\_ArkUI\_PanGesture\_GetVelocityY(event);
        float offsetX = OH\_ArkUI\_PanGesture\_GetOffsetX(event);
        float offsetY = OH\_ArkUI\_PanGesture\_GetOffsetY(event);
        float scale = OH\_ArkUI\_PinchGesture\_GetScale(event);
        float centerX = OH\_ArkUI\_PinchGesture\_GetCenterX(event);
        float centerY = OH\_ArkUI\_PinchGesture\_GetCenterY(event);
        float angle = OH\_ArkUI\_SwipeGesture\_GetAngle(event);
        float velocityS = OH\_ArkUI\_SwipeGesture\_GetVelocity(event);
        float angleR = OH\_ArkUI\_RotationGesture\_GetAngle(event);
        float repeat = OH\_ArkUI\_LongPress\_GetRepeatCount(event);
        
        // 通过日志查看
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, swipeGesture "
                     "callback actionType: %{public}d, velocity%{public}f,velocityX "
                     "%{public}f; "
                     "velocityY %{public}f, offsetX %{public}f, offsetY %{public}f, scale %{public}f, centerX "
                     "%{public}f centerY"
                     " %{public}f angle %{public}f velocityS %{public}f angleR %{public}f repeat %{public}f",
                     actionType, velocity, velocityX, velocityY, offsetX, offsetY, scale, centerX, centerY, angle,
                     velocityS, angleR, repeat);

        ArkUI\_NumberValue value\[\] = {{.f32 = 0}, {.f32 = 0}, {.f32 = 0}, {.f32 = angleR}, {.f32 = 0}};
        ArkUI\_AttributeItem item = {value, ITEM\_SIZE\_FIVE};
        auto column = reinterpret\_cast<ArkUI\_NodeHandle>(extraParam);
        nodeAPI->setAttribute(column, NODE\_ROTATE, &item);
    };

    gestureApi->setGestureEventTarget(
        swipeGesture, GESTURE\_EVENT\_ACTION\_ACCEPT | GESTURE\_EVENT\_ACTION\_UPDATE | GESTURE\_EVENT\_ACTION\_END, column,
        onActionCallBack);

    // 将快滑手势添加到手势组
    if (gestureApi->addChildGesture) {
        gestureApi->addChildGesture(groupGesture, swipeGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, addChildGesture swipeGesture");
    }
    // 将手势组设置到组件上
    gestureApi->addGestureToNode(column, groupGesture, PRIORITY, NORMAL\_GESTURE\_MASK);
    return column;
}

**完整示例：**

完整示例请参考[示例工程](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/NdkAddInteractionEvent)。

#### \[h2\]互斥识别

互斥识别组合手势对应的ArkUI\_GroupGestureMode为EXCLUSIVE\_GROUP。互斥识别组合手势中注册的手势将同时进行识别，若有一个手势识别成功，则结束手势识别，其他所有手势识别失败。

以互斥识别滑动手势和捏合手势为例：

// SwipeAndPinchExclusiveGesture.h
#include <arkui/native\_animate.h>
#include <arkui/native\_gesture.h>
#include <arkui/native\_interface.h>
#include <arkui/native\_node.h>
#include <arkui/native\_type.h>
#include <arkui/native\_node\_napi.h>
#include <hilog/log.h>
#include "Common.h"
#include "Function.h"
// ...

ArkUI\_NodeHandle SwipeAndPinchExclusiveGesture()
{
    OH\_ArkUI\_GetModuleInterface(ARKUI\_NATIVE\_NODE, ArkUI\_NativeNodeAPI\_1, nodeAPI);
    if (nodeAPI == nullptr) {
        return nullptr;
    }
    auto column = nodeAPI->createNode(ARKUI\_NODE\_COLUMN);

    // 创建节点
    ArkUI\_NumberValue value\[\] = {{.u32 = 0xff112233}};
    ArkUI\_AttributeItem item = {value, 1};
    nodeAPI->setAttribute(column, NODE\_BACKGROUND\_COLOR, &item);
    ArkUI\_NumberValue widthValue\[\] = {{WIDTH\_SIZE}};
    ArkUI\_AttributeItem width = {widthValue, ITEM\_SIZE\_ONE};
    nodeAPI->setAttribute(column, NODE\_WIDTH, &width);
    ArkUI\_NumberValue heightValue\[\] = {{HEIGHT\_SIZE}};
    ArkUI\_AttributeItem height = {heightValue, ITEM\_SIZE\_ONE};
    nodeAPI->setAttribute(column, NODE\_HEIGHT, &height);

    // 判断是否支持创建手势
    auto gestureApi = reinterpret\_cast<ArkUI\_NativeGestureAPI\_1 \*>(
        OH\_ArkUI\_QueryModuleInterfaceByName(ARKUI\_NATIVE\_GESTURE, "ArkUI\_NativeGestureAPI\_1"));
    if (gestureApi->createGroupGesture) {
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, createGroupGesture api exist");
    } else {
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, createGroupGesture api not exist");
    }
    auto groupGesture = gestureApi->createGroupGesture(ArkUI\_GroupGestureMode::EXCLUSIVE\_GROUP);

    // 创建滑动手势
    auto panGesture = gestureApi->createPanGesture(FINGERS\_NUM, GESTURE\_DIRECTION\_VERTICAL, DURATION\_NUM);
    if (gestureApi->getGestureType) {
        ArkUI\_GestureRecognizerType type = gestureApi->getGestureType(panGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog panGesture, ArkUI\_GestureRecognizerType %{public}d",
                     type);
    }
    // 给滑动手势绑定回调
    auto onActionCallBackPan = \[\](ArkUI\_GestureEvent \*event, void \*extraParam) {
        ArkUI\_GestureEventActionType actionType = OH\_ArkUI\_GestureEvent\_GetActionType(event);

        float velocity = OH\_ArkUI\_PanGesture\_GetVelocity(event);
        float velocityX = OH\_ArkUI\_PanGesture\_GetVelocityX(event);
        float velocityY = OH\_ArkUI\_PanGesture\_GetVelocityY(event);
        float offsetX = OH\_ArkUI\_PanGesture\_GetOffsetX(event);
        float offsetY = OH\_ArkUI\_PanGesture\_GetOffsetY(event);
        float scale = OH\_ArkUI\_PinchGesture\_GetScale(event);
        float centerX = OH\_ArkUI\_PinchGesture\_GetCenterX(event);
        float centerY = OH\_ArkUI\_PinchGesture\_GetCenterY(event);
        float angle = OH\_ArkUI\_SwipeGesture\_GetAngle(event);
        float velocityS = OH\_ArkUI\_SwipeGesture\_GetVelocity(event);
        float angleR = OH\_ArkUI\_RotationGesture\_GetAngle(event);
        float repeat = OH\_ArkUI\_LongPress\_GetRepeatCount(event);

        // 通过日志查看
        OH\_LOG\_Print(
            LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
            "NdkAddInteractionEvent\_GestureSampleLog, panGesture callback actionType: %{public}d, "
            "velocity %{public}f,velocityX %{public}f; "
            "velocityY %{public}f, offsetX %{public}f, offsetY %{public}f, scale %{public}fcenterX "
            "%{public}f centerY"
            " %{public}f angle %{public}f velocityS %{public}f angleR %{public}f repeat %{public}f",
            actionType, velocity, velocityX, velocityY, offsetX, offsetY, scale, centerX, centerY, angle, velocityS,
            angleR, repeat);
    };
    gestureApi->setGestureEventTarget(panGesture,
                                      GESTURE\_EVENT\_ACTION\_ACCEPT | GESTURE\_EVENT\_ACTION\_UPDATE |
                                          GESTURE\_EVENT\_ACTION\_END | GESTURE\_EVENT\_ACTION\_CANCEL,
                                      column, onActionCallBackPan);
    // 将滑动手势添加到手势组
    if (gestureApi->addChildGesture) {
        gestureApi->addChildGesture(groupGesture, panGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, addChildGesture panGesture");
    }
    // 创建捏合手势
    auto pinchGesture = gestureApi->createPinchGesture(0, 0);
    if (gestureApi->getGestureType) {
        ArkUI\_GestureRecognizerType type = gestureApi->getGestureType(pinchGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog pinchGesture, "
                     "ArkUI\_GestureRecognizerType %{public}d", type);
    }
    // 给捏合手势绑定回调
    auto onActionCallBack = \[\](ArkUI\_GestureEvent \*event, void \*extraParam) {
        ArkUI\_GestureEventActionType actionType = OH\_ArkUI\_GestureEvent\_GetActionType(event);

        float velocity = OH\_ArkUI\_PanGesture\_GetVelocity(event);
        float velocityX = OH\_ArkUI\_PanGesture\_GetVelocityX(event);
        float velocityY = OH\_ArkUI\_PanGesture\_GetVelocityY(event);
        float offsetX = OH\_ArkUI\_PanGesture\_GetOffsetX(event);
        float offsetY = OH\_ArkUI\_PanGesture\_GetOffsetY(event);
        float scale = OH\_ArkUI\_PinchGesture\_GetScale(event);
        float centerX = OH\_ArkUI\_PinchGesture\_GetCenterX(event);
        float centerY = OH\_ArkUI\_PinchGesture\_GetCenterY(event);
        float angle = OH\_ArkUI\_SwipeGesture\_GetAngle(event);
        float velocityS = OH\_ArkUI\_SwipeGesture\_GetVelocity(event);
        float angleR = OH\_ArkUI\_RotationGesture\_GetAngle(event);
        float repeat = OH\_ArkUI\_LongPress\_GetRepeatCount(event);
        
        OH\_LOG\_Print(
            LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
            "NdkAddInteractionEvent\_GestureSampleLog, pinchGesture callback actionType: %{public}d, "
            "velocity %{public}f,velocityX %{public}f; "
            "velocityY %{public}f, offsetX %{public}f, offsetY %{public}f, scale %{public}fcenterX "
            "%{public}f centerY"
            " %{public}f angle %{public}f velocityS %{public}f angleR %{public}f repeat %{public}f",
            actionType, velocity, velocityX, velocityY, offsetX, offsetY, scale, centerX, centerY, angle, velocityS,
            angleR, repeat);
        ArkUI\_NumberValue value\[\] = {{.f32 = scale}, {.f32 = scale}};
        ArkUI\_AttributeItem item = {value, ITEM\_SIZE\_TWO};
        auto column = reinterpret\_cast<ArkUI\_NodeHandle>(extraParam);
        nodeAPI->setAttribute(column, NODE\_SCALE, &item);
    };
    gestureApi->setGestureEventTarget(pinchGesture,
                                      GESTURE\_EVENT\_ACTION\_ACCEPT | GESTURE\_EVENT\_ACTION\_UPDATE |
                                          GESTURE\_EVENT\_ACTION\_END | GESTURE\_EVENT\_ACTION\_CANCEL,
                                      column, onActionCallBack);
    // 将捏合手势添加到手势组
    if (gestureApi->addChildGesture) {
        gestureApi->addChildGesture(groupGesture, pinchGesture);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                     "NdkAddInteractionEvent\_GestureSampleLog, addChildGesture pinchGesture");
    }
    // 将手势组设置到组件上
    gestureApi->addGestureToNode(column, groupGesture, PRIORITY, NORMAL\_GESTURE\_MASK);
    return column;
}

**完整示例：**

完整示例请参考[示例工程](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/NdkAddInteractionEvent)。

#### \[h2\]自定义手势判定

当用户的操作符合某个手势识别器，该识别器即将触发成功时，可通过自定义手势判定能力来动态决策，是否希望该识别器被系统认定为识别成功。通过setGestureInterrupterToNode接口，绑定一个回调在该组件上，但组件上的某个手势即将识别成功时，通过返回CONTINUE或REJECT来决定是否将成功机会让给其它手势识别器。

在上文绑定手势事件的示例中按照如下方式进行调整即可实现自定义手势判定。

1.  创建自定义手势判定回调。
    
    auto onInterruptCallback = \[\](ArkUI\_GestureInterruptInfo \*info) -> ArkUI\_GestureInterruptResult {
        // 获取是否系统手势
        auto sysTag = OH\_ArkUI\_GestureInterruptInfo\_GetSystemFlag(info);
        // 获取拦截的手势指针
        auto recognizer = OH\_ArkUI\_GestureInterruptInfo\_GetRecognizer(info);
        // 获取系统手势类型
        auto systemRecognizerType = OH\_ArkUI\_GestureInterruptInfo\_GetSystemRecognizerType(info);
        // 获取手势事件
        auto gestureEvent = OH\_ArkUI\_GestureInterruptInfo\_GetGestureEvent(info);
        auto inputEvent = OH\_ArkUI\_GestureEvent\_GetRawInputEvent(gestureEvent);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
            "NdkAddInteractionEvent\_eventInfo longPressGesture");
        if (sysTag) {
            // 如果是系统手势则不拦截
            return GESTURE\_INTERRUPT\_RESULT\_CONTINUE;
        } else {
            // 不是系统手势则拒绝
            return GESTURE\_INTERRUPT\_RESULT\_REJECT;
        }
    };
    
2.  绑定手势判定和节点。
    
    gestureApi->setGestureInterrupterToNode(column, onInterruptCallback);
    

经过上述修改，将原本可以生效的长按手势做了拦截，即，此时再对Column节点长按将不会触发长按的手势回调。

#### 获取事件信息

绑定手势事件已详细说明如何将手势绑定到节点上。在回调执行时，ArkUI框架提供了[OH\_ArkUI\_GestureEvent\_GetRawInputEvent()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-gesture-h#oh_arkui_gestureevent_getrawinputevent)接口，可从手势事件中获取基础事件对象。之后，可通过调用[OH\_ArkUI\_PointerEvent\_GetDisplayX()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-ui-input-event-h#oh_arkui_pointerevent_getdisplayx)、[OH\_ArkUI\_PointerEvent\_GetDisplayXByIndex()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-ui-input-event-h#oh_arkui_pointerevent_getdisplayxbyindex)、[OH\_ArkUI\_UIInputEvent\_GetAction()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-ui-input-event-h#oh_arkui_uiinputevent_getaction)和[OH\_ArkUI\_UIInputEvent\_GetEventTime()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-ui-input-event-h#oh_arkui_uiinputevent_geteventtime)等接口，从基础事件中获取更多信息。应用依据获取的信息，在手势事件执行过程中实现差异化交互逻辑。

// 设置回调，在触发手势事件时执行回调处理手势事件
auto onActionCallback = \[\](ArkUI\_GestureEvent \*event, void \*extraParams) {
    // 从手势事件获取基础事件对象
    auto \*inputEvent = OH\_ArkUI\_GestureEvent\_GetRawInputEvent(event);
    // 从基础事件获取事件信息
    auto x = OH\_ArkUI\_PointerEvent\_GetX(inputEvent);
    auto y = OH\_ArkUI\_PointerEvent\_GetY(inputEvent);
    auto displayX = OH\_ArkUI\_PointerEvent\_GetDisplayX(inputEvent);
    auto displayY = OH\_ArkUI\_PointerEvent\_GetDisplayY(inputEvent);
    auto windowX = OH\_ArkUI\_PointerEvent\_GetWindowX(inputEvent);
    auto windowY = OH\_ArkUI\_PointerEvent\_GetWindowY(inputEvent);
    auto pointerCount = OH\_ArkUI\_PointerEvent\_GetPointerCount(inputEvent);
    auto xByIndex = OH\_ArkUI\_PointerEvent\_GetXByIndex(inputEvent, 0);
    auto yByIndex = OH\_ArkUI\_PointerEvent\_GetYByIndex(inputEvent, 0);
    auto displayXByIndex = OH\_ArkUI\_PointerEvent\_GetDisplayXByIndex(inputEvent, 0);
    auto displayYByIndex = OH\_ArkUI\_PointerEvent\_GetDisplayYByIndex(inputEvent, 0);
    auto windowXByIndex = OH\_ArkUI\_PointerEvent\_GetWindowXByIndex(inputEvent, 0);
    auto windowYByIndex = OH\_ArkUI\_PointerEvent\_GetWindowYByIndex(inputEvent, 0);
    auto pointerId = OH\_ArkUI\_PointerEvent\_GetPointerId(inputEvent, 0);
    auto pressure = OH\_ArkUI\_PointerEvent\_GetPressure(inputEvent, 0);
    auto action = OH\_ArkUI\_UIInputEvent\_GetAction(inputEvent);
    auto eventTime = OH\_ArkUI\_UIInputEvent\_GetEventTime(inputEvent);
    auto sourceType = OH\_ArkUI\_UIInputEvent\_GetSourceType(inputEvent);
    auto type = OH\_ArkUI\_UIInputEvent\_GetType(inputEvent);
    std::string eventInfo =
        "x: " + std::to\_string(x) + ", y: " + std::to\_string(y) +
        ", displayX: " + std::to\_string(displayX) + ", displayY: " + std::to\_string(displayY) +
        ", windowX: " + std::to\_string(windowX) + ", windowY: " + std::to\_string(windowY) + "\\n" +
        ", pointerCount: " + std::to\_string(pointerCount) + ", xByIndex: " + std::to\_string(xByIndex) +
        ", yByIndex: " + std::to\_string(yByIndex) +
        ", displayXByIndex: " + std::to\_string(displayXByIndex) +
        ", displayYByIndex: " + std::to\_string(displayYByIndex) +
        ", windowXByIndex: " + std::to\_string(windowXByIndex) +
        ", windowYByIndex: " + std::to\_string(windowYByIndex) + "\\n" +
        ", pointerId: " + std::to\_string(pointerId) + ", pressure: " + std::to\_string(pressure) +
        ", action: " + std::to\_string(action) + ", eventTime: " + std::to\_string(eventTime) +
        ", sourceType: " + std::to\_string(sourceType) + ", type: " + std::to\_string(type);
    OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "\[Sample\_NdkAddInteractionEvent\]",
                 "NdkAddInteractionEvent\_eventInfoOfCommonEvent eventInfo = %{public}s", eventInfo.c\_str());
};
// 创建一个单指点击手势
auto TapGesture = gestureApi->createTapGesture(COUNT\_NUM\_1, FINGERS\_NUM\_1);
// 将事件回调绑定到TapGesture上，触发手势后，通过回调函数处理手势事件
gestureApi->setGestureEventTarget(TapGesture,
                                  GESTURE\_EVENT\_ACTION\_ACCEPT | GESTURE\_EVENT\_ACTION\_UPDATE |
                                  GESTURE\_EVENT\_ACTION\_END | GESTURE\_EVENT\_ACTION\_CANCEL,
                                  column, onActionCallback);
// 将手势添加到column组件上，使column组件可以触发单指点击手势
gestureApi->addGestureToNode(column, TapGesture, ArkUI\_GesturePriority::PARALLEL,
                             ArkUI\_GestureMask::NORMAL\_GESTURE\_MASK);