• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 绑定手势事件
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @jiangtao92-->
5<!--Designer: @piggyguy-->
6<!--Tester: @songyanhong-->
7<!--Adviser: @HelloCrease-->
8
9
10ArkUI开发框架在NDK接口主要提供点击手势、拖动手势、滑动手势、长按手势、捏合手势和旋转手势,通过给指定的组件绑定不同的手势并设置相应的回调,实现期望的手势交互能力。
11
12
13下面通过一个简单的示例来介绍如何实现手势绑定。
14
15
161. 创建一个Column节点,用于绑定手势。
17   ```
18   // 创建Column节点
19   auto column = nodeAPI->createNode(ARKUI_NODE_COLUMN);
20   // 设置背景色
21   ArkUI_NumberValue value[] = {{.u32 = 0xff112233}};
22   ArkUI_AttributeItem item = {value, 1};
23   nodeAPI->setAttribute(column, NODE_BACKGROUND_COLOR, &item);
24   // 设置宽度
25   ArkUI_NumberValue widthValue[] = {{400}};
26   ArkUI_AttributeItem width = {widthValue, 1};
27   nodeAPI->setAttribute(column, NODE_WIDTH, &width);
28   // 设置高度
29   ArkUI_NumberValue heightValue[] = {{400}};
30   ArkUI_AttributeItem height = {heightValue, 1};
31   nodeAPI->setAttribute(column, NODE_HEIGHT, &height);
32   ```
33
342. 创建一个单指长按1秒并持续响应的长按手势。
35   ```
36   // 获取手势Native接口集合
37   auto gestureApi = reinterpret_cast<ArkUI_NativeGestureAPI_1 *>(
38               OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_GESTURE, "ArkUI_NativeGestureAPI_1"));
39   // 创建长按手势
40   auto longPressGesture = gestureApi->createLongPressGesture(1, true, 1000);
41   ```
42
433. 将创建的手势和步骤一中创建的Column节点绑定。
44   ```
45   // 设置回调
46   auto onActionCallBack = [](ArkUI_GestureEvent *event, void *extraParam) {
47       // 回调内容
48   };
49
50   // 将手势设置到组件上
51   gestureApi->setGestureEventTarget(longPressGesture, GESTURE_EVENT_ACTION_ACCEPT | GESTURE_EVENT_ACTION_UPDATE | GESTURE_EVENT_ACTION_END, column, onActionCallBack);
52
53   gestureApi->addGestureToNode(column, longPressGesture, PARALLEL, NORMAL_GESTURE_MASK);
54   ```
55
56
57## 单一手势
58
59通过上文的示例已经了解了如何将手势绑定在节点上,接下来将分别介绍不同手势的创建方法。
60
61- 点击手势
62  通过给组件绑定点击手势可在组件被点击时触发此回调,可指定触发回调需要的点击次数和手指个数。
63
64  ```
65   // 获取手势Native接口集合
66   auto gestureApi = reinterpret_cast<ArkUI_NativeGestureAPI_1 *>(
67               OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_GESTURE, "ArkUI_NativeGestureAPI_1"));
68   // 创建点击手势
69   auto tapGesture = gestureApi->createTapGesture(1, 1);
70  ```
71
72- 拖动手势
73  通过给组件绑定拖动手势可在用户拖动组件时触发回调,可指定触发回调需要的手指个数、拖动方向、拖动距离。单位为px。
74  ```
75    // 获取手势Native接口集合
76    auto gestureApi = reinterpret_cast<ArkUI_NativeGestureAPI_1 *>(
77        OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_GESTURE, "ArkUI_NativeGestureAPI_1"));
78    // 创建拖动手势
79    auto panGesture = gestureApi->createPanGesture(1, GESTURE_DIRECTION_ALL, 1);
80  ```
81
82- 长按手势
83  通过给组件绑定长按手势可在用户长按组件时触发回调,可指定触发回调需要的手指个数、长按时间(单位毫秒)、是否连续触发。
84
85  ```
86    // 获取手势Native接口集合
87    auto gestureApi = reinterpret_cast<ArkUI_NativeGestureAPI_1 *>(
88        OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_GESTURE, "ArkUI_NativeGestureAPI_1"));
89    // 创建长按手势
90    auto longPressGesture = gestureApi->createLongPressGesture(1, true, 1000);
91  ```
92
93- 捏合手势
94  通过给组件绑定捏合手势可在用户捏合组件时触发回调,可指定触发回调需要的手指个数(最小为2)、捏合距离(单位px)。
95
96  ```
97    // 获取手势Native接口集合
98    auto gestureApi = reinterpret_cast<ArkUI_NativeGestureAPI_1 *>(
99        OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_GESTURE, "ArkUI_NativeGestureAPI_1"));
100    // 创建捏合手势
101    auto pinchGesture = gestureApi->createPinchGesture(1, 10);
102  ```
103
104- 旋转手势
105  通过给组件绑定旋转手势可在用户旋转组件时触发回调,可指定触发回调需要的手指个数(最小为2)、旋转角度。
106
107  ```
108    // 获取手势Native接口集合
109    auto gestureApi = reinterpret_cast<ArkUI_NativeGestureAPI_1 *>(
110        OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_GESTURE, "ArkUI_NativeGestureAPI_1"));
111    // 创建旋转手势
112    auto rotationGesture = gestureApi->createRotationGesture(1, 10);
113  ```
114
115- 滑动手势
116  通过给组件绑定滑动手势可在用户滑动组件时触发回调,可指定触发回调需要的手指个数(最小为1)、滑动方向、滑动速度(单位px/s)。
117
118  ```
119    // 获取手势Native接口集合
120    auto gestureApi = reinterpret_cast<ArkUI_NativeGestureAPI_1 *>(
121        OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_GESTURE, "ArkUI_NativeGestureAPI_1"));
122    // 创建滑动手势
123    auto swipeGesture = gestureApi->createSwipeGesture(1, GESTURE_DIRECTION_ALL, 50);
124
125  ```
126
127
128## 组合手势
129
130可以将多个不同类型的手势组合在一起,形成一个手势组,这个手势组可以作为一个识别整体,达到对用户多个不同类型手势序列的识别目的。
131
132通过设置[ArkUI_GroupGestureMode](../reference/apis-arkui/capi-native-gesture-h.md#arkui_groupgesturemode)来指定这个手势组的识别模式,即组内的手势之间的关系,包含顺序识别SEQUENTIAL_GROUP,并行识别PARALLEL_GROUP,互斥识别EXCLUSIVE_GROUP。
133
134
135### 顺序识别
136
137顺序识别组合手势对应的ArkUI_GroupGestureMode为SEQUENTIAL_GROUP。顺序识别组合手势将按照手势的注册顺序识别手势,直到所有的手势识别成功。当顺序识别组合手势中有一个手势识别失败时,后续手势识别均失败。顺序识别手势组仅有最后一个手势可以响应[GESTURE_EVENT_ACTION_END](../reference/apis-arkui/capi-native-gesture-h.md#arkui_gestureeventactiontype)。
138
139以顺序识别长按和滑动手势为例:
140
141```
142#include "napi/native_api.h"
143#include <arkui/native_animate.h>
144#include <arkui/native_gesture.h>
145#include <arkui/native_interface.h>
146#include <arkui/native_node_napi.h>
147#include <hilog/log.h>
148const unsigned int LOG_PRINT_DOMAIN = 0xFF00;
149
150ArkUI_NodeHandle testGestureExample() {
151    auto column = nodeAPI->createNode(ARKUI_NODE_COLUMN);
152
153    // 创建节点
154    ArkUI_NumberValue value[] = {{.u32 = 0xff112233}};
155    ArkUI_AttributeItem item = {value, 1};
156    nodeAPI->setAttribute(column, NODE_BACKGROUND_COLOR, &item);
157    ArkUI_NumberValue widthValue[] = {{200}};
158    ArkUI_AttributeItem width = {widthValue, 1};
159    nodeAPI->setAttribute(column, NODE_WIDTH, &width);
160    ArkUI_NumberValue heightValue[] = {{200}};
161    ArkUI_AttributeItem height = {heightValue, 1};
162    nodeAPI->setAttribute(column, NODE_HEIGHT, &height);
163
164    // 判断是否支持创建手势
165    auto gestureApi = reinterpret_cast<ArkUI_NativeGestureAPI_1 *>(
166        OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_GESTURE, "ArkUI_NativeGestureAPI_1"));
167    if (gestureApi->createGroupGesture) {
168        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
169                     "GestureSampleLog, createGroupGesture api exist");
170    } else {
171        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
172                     "GestureSampleLog, createGroupGesture api not exist");
173    }
174    auto groupGesture = gestureApi->createGroupGesture(ArkUI_GroupGestureMode::SEQUENTIAL_GROUP);
175
176    // 创建长按手势
177    auto longPressGesture = gestureApi->createLongPressGesture(1, true, 500);
178    if (gestureApi->getGestureType) {
179        ArkUI_GestureRecognizerType type = gestureApi->getGestureType(longPressGesture);
180        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
181                     "GestureSampleLog longPressGesture,ArkUI_GestureRecognizerType%{public}d", type);
182    }
183    // 给长按手势定回调
184    auto onActionCallBackPanLongPress = [](ArkUI_GestureEvent *event, void *extraParam) {
185        ArkUI_GestureEventActionType actionType = OH_ArkUI_GestureEvent_GetActionType(event);
186
187        float velocity = OH_ArkUI_PanGesture_GetVelocity(event);
188        float velocityX = OH_ArkUI_PanGesture_GetVelocityX(event);
189        float velocityY = OH_ArkUI_PanGesture_GetVelocityY(event);
190        float offsetX = OH_ArkUI_PanGesture_GetOffsetX(event);
191        float offsetY = OH_ArkUI_PanGesture_GetOffsetY(event);
192        float scale = OH_ArkUI_PinchGesture_GetScale(event);
193        float centerX = OH_ArkUI_PinchGesture_GetCenterX(event);
194        float centerY = OH_ArkUI_PinchGesture_GetCenterY(event);
195        float angle = OH_ArkUI_SwipeGesture_GetAngle(event);
196        float VelocityS = OH_ArkUI_SwipeGesture_GetVelocity(event);
197        float angleR = OH_ArkUI_RotationGesture_GetAngle(event);
198        float repeat = OH_ArkUI_LongPress_GetRepeatCount(event);
199
200        OH_LOG_Print(
201            LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
202            "GestureSampleLog,longPressGesturecallback actionType:%{public}d,velocity%{public}f,velocityX"
203            "%{public}f;"
204            "velocityY%{public}f,offsetX%{public}f,offsetY%{public}f,scale%{public}fcenterX"
205            "%{public}fcenterY"
206            "%{public}fangle%{public}fVelocityS%{public}fangleR%{public}frepeat%{public}f",
207            actionType, velocity, velocityX, velocityY, offsetX, offsetY, scale, centerX, centerY, angle, VelocityS,
208            angleR, repeat);
209    };
210    gestureApi->setGestureEventTarget(longPressGesture,
211                                      GESTURE_EVENT_ACTION_ACCEPT | GESTURE_EVENT_ACTION_UPDATE | GESTURE_EVENT_ACTION_CANCEL,
212                                      column, onActionCallBackPanLongPress);
213
214    // 将长按手势添加到手势组
215    if (gestureApi->addChildGesture) {
216        gestureApi->addChildGesture(groupGesture, longPressGesture);
217        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "GestureSampleLog, addChildGesture longPressGesture");
218    }
219    // 创建滑动手势 swipe
220    auto swipeGesture = gestureApi->createSwipeGesture(1, GESTURE_DIRECTION_ALL, 100);
221    if (gestureApi->getGestureType) {
222        ArkUI_GestureRecognizerType type = gestureApi->getGestureType(swipeGesture);
223        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
224                     "GestureSampleLog, ArkUI_GestureRecognizerType %{public}d", type);
225    }
226    // 给滑动手势绑定回调
227    auto onActionCallBack = [](ArkUI_GestureEvent *event, void *extraParam) {
228        ArkUI_GestureEventActionType actionType = OH_ArkUI_GestureEvent_GetActionType(event);
229
230        float velocity = OH_ArkUI_PanGesture_GetVelocity(event);
231        float velocityX = OH_ArkUI_PanGesture_GetVelocityX(event);
232        float velocityY = OH_ArkUI_PanGesture_GetVelocityY(event);
233        float offsetX = OH_ArkUI_PanGesture_GetOffsetX(event);
234        float offsetY = OH_ArkUI_PanGesture_GetOffsetY(event);
235        float scale = OH_ArkUI_PinchGesture_GetScale(event);
236        float centerX = OH_ArkUI_PinchGesture_GetCenterX(event);
237        float centerY = OH_ArkUI_PinchGesture_GetCenterY(event);
238        float angle = OH_ArkUI_SwipeGesture_GetAngle(event);
239        float VelocityS = OH_ArkUI_SwipeGesture_GetVelocity(event);
240        float angleR = OH_ArkUI_RotationGesture_GetAngle(event);
241        float repeat = OH_ArkUI_LongPress_GetRepeatCount(event);
242
243
244        // 通过日志查看
245        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
246                     "GestureSampleLog, swipeGesture callback actionType: %{public}d, velocity "
247                     "%{public}f,velocityX "
248                     "%{public}f; "
249                     "velocityY %{public}f, offsetX %{public}f, offsetY %{public}f, scale %{public}fcenterX "
250                     "%{public}f centerY"
251                     " %{public}f angle %{public}f VelocityS %{public}f angleR %{public}f repeat %{public}f",
252                     actionType, velocity, velocityX, velocityY, offsetX, offsetY, scale, centerX, centerY, angle,
253                     VelocityS, angleR, repeat);
254
255        ArkUI_NumberValue value[] = {{.f32 = 0}, {.f32 = 0}, {.f32 = 0}, {.f32 = angleR}, {.f32 = 0}};
256        ArkUI_AttributeItem item = {value, 5};
257        auto column = reinterpret_cast<ArkUI_NodeHandle>(extraParam);
258        nodeAPI->setAttribute(column, NODE_ROTATE, &item);
259    };
260
261    gestureApi->setGestureEventTarget(
262        swipeGesture, GESTURE_EVENT_ACTION_ACCEPT | GESTURE_EVENT_ACTION_UPDATE | GESTURE_EVENT_ACTION_END, column,
263        onActionCallBack);
264
265    // 将滑动手势添加到手势组
266    if (gestureApi->addChildGesture) {
267        gestureApi->addChildGesture(groupGesture, swipeGesture);
268        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
269                     "GestureSampleLog, addChildGesture swipeGesture");
270    }
271    // 将手势组设置到组件上
272    gestureApi->addGestureToNode(column, groupGesture, PRIORITY, NORMAL_GESTURE_MASK);
273    return column;
274}
275```
276
277
278### 并行识别
279
280并行识别组合手势对应的ArkUI_GroupGestureMode为PARALLEL_GROUP。并行识别组合手势中注册的手势将同时进行识别,直到所有手势识别结束。并行识别手势组合中的手势进行识别时互不影响。
281
282以并行识别长按和滑动手势为例:
283
284```
285#include "napi/native_api.h"
286#include <arkui/native_animate.h>
287#include <arkui/native_gesture.h>
288#include <arkui/native_interface.h>
289#include <arkui/native_node_napi.h>
290#include <hilog/log.h>
291const unsigned int LOG_PRINT_DOMAIN = 0xFF00;
292
293ArkUI_NodeHandle testGestureExample() {
294    auto column = nodeAPI->createNode(ARKUI_NODE_COLUMN);
295
296    // 创建节点
297    ArkUI_NumberValue value[] = {{.u32 = 0xff112233}};
298    ArkUI_AttributeItem item = {value, 1};
299    nodeAPI->setAttribute(column, NODE_BACKGROUND_COLOR, &item);
300    ArkUI_NumberValue widthValue[] = {{200}};
301    ArkUI_AttributeItem width = {widthValue, 1};
302    nodeAPI->setAttribute(column, NODE_WIDTH, &width);
303    ArkUI_NumberValue heightValue[] = {{200}};
304    ArkUI_AttributeItem height = {heightValue, 1};
305    nodeAPI->setAttribute(column, NODE_HEIGHT, &height);
306
307    // 判断是否支持创建手势
308    auto gestureApi = reinterpret_cast<ArkUI_NativeGestureAPI_1 *>(
309        OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_GESTURE, "ArkUI_NativeGestureAPI_1"));
310    if (gestureApi->createGroupGesture) {
311        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
312                     "GestureSampleLog, createGroupGesture api exist");
313    } else {
314        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
315                     "GestureSampleLog, createGroupGesture api not exist");
316    }
317
318    // 创建手势组
319    auto groupGesture = gestureApi->createGroupGesture(ArkUI_GroupGestureMode::PARALLEL_GROUP);
320
321    // 创建长按手势
322    auto longPressGesture = gestureApi->createLongPressGesture(1, true, 500);
323    if (gestureApi->getGestureType) {
324        ArkUI_GestureRecognizerType type = gestureApi->getGestureType(longPressGesture);
325        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
326                     "GestureSampleLog,ArkUI_GestureRecognizerType%{public}d", type);
327    }
328    // 给长按手势定回调
329    auto onActionCallBackPanLongPress = [](ArkUI_GestureEvent *event, void *extraParam) {
330        ArkUI_GestureEventActionType actionType = OH_ArkUI_GestureEvent_GetActionType(event);
331
332        float velocity = OH_ArkUI_PanGesture_GetVelocity(event);
333        float velocityX = OH_ArkUI_PanGesture_GetVelocityX(event);
334        float velocityY = OH_ArkUI_PanGesture_GetVelocityY(event);
335        float OffsetX = OH_ArkUI_PanGesture_GetOffsetX(event);
336        float OffsetY = OH_ArkUI_PanGesture_GetOffsetY(event);
337        float scale = OH_ArkUI_PinchGesture_GetScale(event);
338        float CenterX = OH_ArkUI_PinchGesture_GetCenterX(event);
339        float CenterY = OH_ArkUI_PinchGesture_GetCenterY(event);
340        float angle = OH_ArkUI_SwipeGesture_GetAngle(event);
341        float VelocityS = OH_ArkUI_SwipeGesture_GetVelocity(event);
342        float angleR = OH_ArkUI_RotationGesture_GetAngle(event);
343        float repeat = OH_ArkUI_LongPress_GetRepeatCount(event);
344
345        OH_LOG_Print(
346            LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
347            "GestureSampleLog,longPressGesturecallback actionType:%{public}d,velocity%{public}f,velocityX"
348            "%{public}f;"
349            "velocityY%{public}f,OffsetX%{public}f,OffsetY%{public}f,scale%{public}fCenterX"
350            "%{public}fCenterY"
351            "%{public}fangle%{public}fVelocityS%{public}fangleR%{public}frepeat%{public}f",
352            actionType, velocity, velocityX, velocityY, OffsetX, OffsetY, scale, CenterX, CenterY, angle, VelocityS,
353            angleR, repeat);
354    };
355    gestureApi->setGestureEventTarget(longPressGesture,
356                                      GESTURE_EVENT_ACTION_ACCEPT | GESTURE_EVENT_ACTION_UPDATE |
357                                            GESTURE_EVENT_ACTION_CANCEL,
358                                      column, onActionCallBackPanLongPress);
359
360    // 将长按手势添加到手势组
361    if (gestureApi->addChildGesture) {
362        gestureApi->addChildGesture(groupGesture, longPressGesture);
363        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "GestureSampleLog, addChildGesture longPressGesture");
364    }
365    // 创建滑动手势 swipe
366    auto swipeGesture = gestureApi->createSwipeGesture(1, GESTURE_DIRECTION_ALL, 100);
367    if (gestureApi->getGestureType) {
368        ArkUI_GestureRecognizerType type = gestureApi->getGestureType(swipeGesture);
369        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
370                     "GestureSampleLog, ArkUI_GestureRecognizerType %{public}d", type);
371    }
372    // 给滑动手势绑定回调
373    auto onActionCallBack = [](ArkUI_GestureEvent *event, void *extraParam) {
374        ArkUI_GestureEventActionType actionType = OH_ArkUI_GestureEvent_GetActionType(event);
375
376        float velocity = OH_ArkUI_PanGesture_GetVelocity(event);
377        float velocityX = OH_ArkUI_PanGesture_GetVelocityX(event);
378        float velocityY = OH_ArkUI_PanGesture_GetVelocityY(event);
379        float OffsetX = OH_ArkUI_PanGesture_GetOffsetX(event);
380        float OffsetY = OH_ArkUI_PanGesture_GetOffsetY(event);
381        float scale = OH_ArkUI_PinchGesture_GetScale(event);
382        float CenterX = OH_ArkUI_PinchGesture_GetCenterX(event);
383        float CenterY = OH_ArkUI_PinchGesture_GetCenterY(event);
384        float angle = OH_ArkUI_SwipeGesture_GetAngle(event);
385        float VelocityS = OH_ArkUI_SwipeGesture_GetVelocity(event);
386        float angleR = OH_ArkUI_RotationGesture_GetAngle(event);
387        float repeat = OH_ArkUI_LongPress_GetRepeatCount(event);
388
389
390        // 通过日志查看
391        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
392                     "GestureSampleLog, swipeGesture callback actionType: %{public}d, velocity "
393                     "%{public}f,velocityX "
394                     "%{public}f; "
395                     "velocityY %{public}f, OffsetX %{public}f, OffsetY %{public}f, scale %{public}fCenterX "
396                     "%{public}f CenterY"
397                     " %{public}f angle %{public}f VelocityS %{public}f angleR %{public}f repeat %{public}f",
398                     actionType, velocity, velocityX, velocityY, OffsetX, OffsetY, scale, CenterX, CenterY, angle,
399                     VelocityS, angleR, repeat);
400
401        ArkUI_NumberValue value[] = {{.f32 = 0}, {.f32 = 0}, {.f32 = 0}, {.f32 = angleR}, {.f32 = 0}};
402        ArkUI_AttributeItem item = {value, 5};
403        auto column = reinterpret_cast<ArkUI_NodeHandle>(extraParam);
404        nodeAPI->setAttribute(column, NODE_ROTATE, &item);
405    };
406
407    gestureApi->setGestureEventTarget(
408        swipeGesture, GESTURE_EVENT_ACTION_ACCEPT | GESTURE_EVENT_ACTION_UPDATE | GESTURE_EVENT_ACTION_END, column,
409        onActionCallBack);
410
411    // 将滑动手势添加到手势组
412    if (gestureApi->addChildGesture) {
413        gestureApi->addChildGesture(groupGesture, swipeGesture);
414        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
415                     "GestureSampleLog, addChildGesture swipeGesture");
416    }
417    // 将手势组设置到组件上
418    gestureApi->addGestureToNode(column, groupGesture, PRIORITY, NORMAL_GESTURE_MASK);
419    return column;
420}
421```
422
423
424### 互斥识别
425
426互斥识别组合手势对应的ArkUI_GroupGestureMode为EXCLUSIVE_GROUP。互斥识别组合手势中注册的手势将同时进行识别,若有一个手势识别成功,则结束手势识别,其他所有手势识别失败。
427
428以互斥识别拖动手势和捏合手势为例:
429
430```
431#include "napi/native_api.h"
432#include <arkui/native_animate.h>
433#include <arkui/native_gesture.h>
434#include <arkui/native_interface.h>
435#include <arkui/native_node_napi.h>
436#include <hilog/log.h>
437const unsigned int LOG_PRINT_DOMAIN = 0xFF00;
438static ArkUI_NativeNodeAPI_1 *nodeAPI = nullptr;
439
440ArkUI_NodeHandle testGestureExample() {
441    OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nodeAPI);
442    if (nodeAPI == nullptr) {
443        return nullptr;
444    }
445    auto column = nodeAPI->createNode(ARKUI_NODE_COLUMN);
446
447    // 创建节点
448    ArkUI_NumberValue value[] = {{.u32 = 0xff112233}};
449    ArkUI_AttributeItem item = {value, 1};
450    nodeAPI->setAttribute(column, NODE_BACKGROUND_COLOR, &item);
451    ArkUI_NumberValue widthValue[] = {{200}};
452    ArkUI_AttributeItem width = {widthValue, 1};
453    nodeAPI->setAttribute(column, NODE_WIDTH, &width);
454    ArkUI_NumberValue heightValue[] = {{200}};
455    ArkUI_AttributeItem height = {heightValue, 1};
456    nodeAPI->setAttribute(column, NODE_HEIGHT, &height);
457
458    // 判断是否支持创建手势
459    auto gestureApi = reinterpret_cast<ArkUI_NativeGestureAPI_1 *>(
460        OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_GESTURE, "ArkUI_NativeGestureAPI_1"));
461    if (gestureApi->createGroupGesture) {
462        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
463                     "GestureSampleLog, createGroupGesture api exist");
464    } else {
465        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
466                     "GestureSampleLog, createGroupGesture api not exist");
467    }
468    auto groupGesture = gestureApi->createGroupGesture(ArkUI_GroupGestureMode::EXCLUSIVE_GROUP);
469
470    // 创建拖动手势
471    auto panGesture = gestureApi->createPanGesture(1, GESTURE_DIRECTION_VERTICAL, 5);
472    if (gestureApi->getGestureType) {
473        ArkUI_GestureRecognizerType type = gestureApi->getGestureType(panGesture);
474        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
475                     "GestureSampleLog panGesture, ArkUI_GestureRecognizerType %{public}d", type);
476    }
477    // 给拖动手势绑定回调
478    auto onActionCallBackPan = [](ArkUI_GestureEvent *event, void *extraParam) {
479        ArkUI_GestureEventActionType actionType = OH_ArkUI_GestureEvent_GetActionType(event);
480
481        float velocity = OH_ArkUI_PanGesture_GetVelocity(event);
482        float velocityX = OH_ArkUI_PanGesture_GetVelocityX(event);
483        float velocityY = OH_ArkUI_PanGesture_GetVelocityY(event);
484        float OffsetX = OH_ArkUI_PanGesture_GetOffsetX(event);
485        float OffsetY = OH_ArkUI_PanGesture_GetOffsetY(event);
486        float scale = OH_ArkUI_PinchGesture_GetScale(event);
487        float CenterX = OH_ArkUI_PinchGesture_GetCenterX(event);
488        float CenterY = OH_ArkUI_PinchGesture_GetCenterY(event);
489        float angle = OH_ArkUI_SwipeGesture_GetAngle(event);
490        float VelocityS = OH_ArkUI_SwipeGesture_GetVelocity(event);
491        float angleR = OH_ArkUI_RotationGesture_GetAngle(event);
492        float repeat = OH_ArkUI_LongPress_GetRepeatCount(event);
493
494        // 通过日志查看
495        OH_LOG_Print(
496            LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
497            "GestureSampleLog, panGesture callback actionType: %{public}d, velocity %{public}f,velocityX "
498            "%{public}f; "
499            "velocityY %{public}f, OffsetX %{public}f, OffsetY %{public}f, scale %{public}fCenterX "
500            "%{public}f CenterY"
501            " %{public}f angle %{public}f VelocityS %{public}f angleR %{public}f repeat %{public}f",
502            actionType, velocity, velocityX, velocityY, OffsetX, OffsetY, scale, CenterX, CenterY, angle, VelocityS,
503            angleR, repeat);
504    };
505    gestureApi->setGestureEventTarget(panGesture,
506                                      GESTURE_EVENT_ACTION_ACCEPT | GESTURE_EVENT_ACTION_UPDATE |
507                                          GESTURE_EVENT_ACTION_END | GESTURE_EVENT_ACTION_CANCEL,
508                                      column, onActionCallBackPan);
509    // 将拖动手势添加到手势组
510    if (gestureApi->addChildGesture) {
511        gestureApi->addChildGesture(groupGesture, panGesture);
512        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "GestureSampleLog, addChildGesture panGesture");
513    }
514    // 创建捏合手势
515    auto pinchGesture = gestureApi->createPinchGesture(0, 0);
516    if (gestureApi->getGestureType) {
517        ArkUI_GestureRecognizerType type = gestureApi->getGestureType(pinchGesture);
518        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
519                     "GestureSampleLog pinchGesture, ArkUI_GestureRecognizerType %{public}d", type);
520    }
521    // 给捏合手势绑定回调
522    auto onActionCallBack = [](ArkUI_GestureEvent *event, void *extraParam) {
523        ArkUI_GestureEventActionType actionType = OH_ArkUI_GestureEvent_GetActionType(event);
524
525        float velocity = OH_ArkUI_PanGesture_GetVelocity(event);
526        float velocityX = OH_ArkUI_PanGesture_GetVelocityX(event);
527        float velocityY = OH_ArkUI_PanGesture_GetVelocityY(event);
528        float OffsetX = OH_ArkUI_PanGesture_GetOffsetX(event);
529        float OffsetY = OH_ArkUI_PanGesture_GetOffsetY(event);
530        float scale = OH_ArkUI_PinchGesture_GetScale(event);
531        float CenterX = OH_ArkUI_PinchGesture_GetCenterX(event);
532        float CenterY = OH_ArkUI_PinchGesture_GetCenterY(event);
533        float angle = OH_ArkUI_SwipeGesture_GetAngle(event);
534        float VelocityS = OH_ArkUI_SwipeGesture_GetVelocity(event);
535        float angleR = OH_ArkUI_RotationGesture_GetAngle(event);
536        float repeat = OH_ArkUI_LongPress_GetRepeatCount(event);
537
538
539        OH_LOG_Print(
540            LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager",
541            "GestureSampleLog, pinchGesture callback actionType: %{public}d, velocity %{public}f,velocityX "
542            "%{public}f; "
543            "velocityY %{public}f, OffsetX %{public}f, OffsetY %{public}f, scale %{public}fCenterX "
544            "%{public}f CenterY"
545            " %{public}f angle %{public}f VelocityS %{public}f angleR %{public}f repeat %{public}f",
546            actionType, velocity, velocityX, velocityY, OffsetX, OffsetY, scale, CenterX, CenterY, angle, VelocityS,
547            angleR, repeat);
548
549
550        ArkUI_NumberValue value[] = {{.f32 = scale}, {.f32 = scale}};
551        ArkUI_AttributeItem item = {value, 2};
552        auto column = reinterpret_cast<ArkUI_NodeHandle>(extraParam);
553        nodeAPI->setAttribute(column, NODE_SCALE, &item);
554    };
555    gestureApi->setGestureEventTarget(pinchGesture,
556                                      GESTURE_EVENT_ACTION_ACCEPT | GESTURE_EVENT_ACTION_UPDATE |
557                                          GESTURE_EVENT_ACTION_END | GESTURE_EVENT_ACTION_CANCEL,
558                                      column, onActionCallBack);
559    // 将捏合手势添加到手势组
560    if (gestureApi->addChildGesture) {
561        gestureApi->addChildGesture(groupGesture, pinchGesture);
562        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "GestureSampleLog, addChildGesture pinchGesture");
563    }
564    // 将手势组设置到组件上
565    gestureApi->addGestureToNode(column, groupGesture, PRIORITY, NORMAL_GESTURE_MASK);
566    return column;
567}
568```
569
570
571### 自定义手势判定
572
573当用户的操作符合某个手势识别器,该识别器即将触发成功时,可通过自定义手势判定能力来动态决策,是否希望该识别器被系统认定为识别成功。通过setGestureInterrupterToNode接口,绑定一个回调在该组件上,但组件上的某个手势即将识别成功时,通过返回CONTINUE或REJECT来决定是否将成功机会让给其它手势识别器。
574
575在上文绑定手势事件的示例中按照如下方式进行调整即可实现自定义手势判定。
576
577
5781. 创建自定义手势判定回调。
579    ```
580    auto onInterruptCallback = [](ArkUI_GestureInterruptInfo *info) -> ArkUI_GestureInterruptResult {
581        // 获取是否系统手势
582        auto systag = OH_ArkUI_GestureInterruptInfo_GetSystemFlag(info);
583        // 获取拦截的手势指针
584        auto recognizer = OH_ArkUI_GestureInterruptInfo_GetRecognizer(info);
585        // 获取系统手势类型
586        auto systemRecognizerType = OH_ArkUI_GestureInterruptInfo_GetSystemRecognizerType(info);
587        // 获取手势事件
588        auto gestureEvent = OH_ArkUI_GestureInterruptInfo_GetGestureEvent(info);
589        auto inputevent = OH_ArkUI_GestureEvent_GetRawInputEvent(gestureEvent);
590
591        if (systag) {
592            // 如果是系统手势则不拦截
593            return GESTURE_INTERRUPT_RESULT_CONTINUE;
594        } else {
595            // 不是系统手势则拒绝
596            return GESTURE_INTERRUPT_RESULT_REJECT;
597        }
598    };
599    ```
600
6012. 绑定手势判定和节点。
602   ```
603   gestureApi->setGestureInterrupterToNode(column, onInterruptCallback);
604   ```
605
606
607经过上述修改,将原本可以生效的长按手势做了拦截,即,此时再对Column节点长按将不会触发长按的手势回调。
608
609## 获取事件信息
610
611绑定手势事件已详细说明如何将手势绑定到节点上。在回调执行时,ArkUI框架提供了[OH_ArkUI_GestureEvent_GetRawInputEvent()](../reference/apis-arkui/capi-native-gesture-h.md#oh_arkui_gestureevent_getrawinputevent)接口,可从手势事件中获取基础事件对象。之后,可通过调用[OH_ArkUI_PointerEvent_GetDisplayX()](../reference/apis-arkui/capi-ui-input-event-h.md#oh_arkui_pointerevent_getdisplayx)、[OH_ArkUI_PointerEvent_GetDisplayXByIndex()](../reference/apis-arkui/capi-ui-input-event-h.md#oh_arkui_pointerevent_getdisplayxbyindex)、[OH_ArkUI_UIInputEvent_GetAction()](../reference/apis-arkui/capi-ui-input-event-h.md#oh_arkui_uiinputevent_getaction)和[OH_ArkUI_UIInputEvent_GetEventTime()](../reference/apis-arkui/capi-ui-input-event-h.md#oh_arkui_uiinputevent_geteventtime)等接口,从基础事件中获取更多信息。应用依据获取的信息,在手势事件执行过程中实现差异化交互逻辑。
612
613   ```cpp
614   // 设置回调,在触发手势事件时执行回调处理手势事件
615   auto onActionCallback = [](ArkUI_GestureEvent *event, void *extraParams) {
616       // 从手势事件获取基础事件对象
617       auto *inputEvent = OH_ArkUI_GestureEvent_GetRawInputEvent(event);
618       // 从基础事件获取事件信息
619       auto x = OH_ArkUI_PointerEvent_GetX(inputEvent);
620       auto y = OH_ArkUI_PointerEvent_GetY(inputEvent);
621       auto displayX = OH_ArkUI_PointerEvent_GetDisplayX(inputEvent);
622       auto displayY = OH_ArkUI_PointerEvent_GetDisplayY(inputEvent);
623       auto windowX = OH_ArkUI_PointerEvent_GetWindowX(inputEvent);
624       auto windowY = OH_ArkUI_PointerEvent_GetWindowY(inputEvent);
625       auto pointerCount = OH_ArkUI_PointerEvent_GetPointerCount(inputEvent);
626       auto xByIndex = OH_ArkUI_PointerEvent_GetXByIndex(inputEvent, 0);
627       auto yByIndex = OH_ArkUI_PointerEvent_GetYByIndex(inputEvent, 0);
628       auto displayXByIndex = OH_ArkUI_PointerEvent_GetDisplayXByIndex(inputEvent, 0);
629       auto displayYByIndex = OH_ArkUI_PointerEvent_GetDisplayYByIndex(inputEvent, 0);
630       auto windowXByIndex = OH_ArkUI_PointerEvent_GetWindowXByIndex(inputEvent, 0);
631       auto windowYByIndex = OH_ArkUI_PointerEvent_GetWindowYByIndex(inputEvent, 0);
632       auto pointerId = OH_ArkUI_PointerEvent_GetPointerId(inputEvent, 0);
633       auto pressure = OH_ArkUI_PointerEvent_GetPressure(inputEvent, 0);
634       auto action = OH_ArkUI_UIInputEvent_GetAction(inputEvent);
635       auto eventTime = OH_ArkUI_UIInputEvent_GetEventTime(inputEvent);
636       auto sourceType = OH_ArkUI_UIInputEvent_GetSourceType(inputEvent);
637       auto type = OH_ArkUI_UIInputEvent_GetType(inputEvent);
638       std::string eventInfo =
639           "x: " + std::to_string(x) + ", y: " + std::to_string(y) +
640           ", displayX: " + std::to_string(displayX) + ", displayY: " + std::to_string(displayY) +
641           ", windowX: " + std::to_string(windowX) + ", windowY: " + std::to_string(windowY) + "\n" +
642           ", pointerCount: " + std::to_string(pointerCount) + ", xByIndex: " + std::to_string(xByIndex) +
643           ", yByIndex: " + std::to_string(yByIndex) +
644           ", displayXByIndex: " + std::to_string(displayXByIndex) +
645           ", displayYByIndex: " + std::to_string(displayYByIndex) +
646           ", windowXByIndex: " + std::to_string(windowXByIndex) +
647           ", windowYByIndex: " + std::to_string(windowYByIndex) + "\n" +
648           ", pointerId: " + std::to_string(pointerId) + ", pressure: " + std::to_string(pressure) +
649           ", action: " + std::to_string(action) + ", eventTime: " + std::to_string(eventTime) +
650           ", sourceType: " + std::to_string(sourceType) + ", type: " + std::to_string(type);
651       OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfoOfCommonEvent", "eventInfo = %{public}s",
652                       eventInfo.c_str());
653   };
654   // 创建一个单指点击手势
655   auto TapGesture = gestureApi->createTapGesture(1, 1);
656   // 将事件回调绑定到TapGesture上,触发手势后,通过回调函数处理手势事件
657   gestureApi->setGestureEventTarget(TapGesture,
658                                       GESTURE_EVENT_ACTION_ACCEPT | GESTURE_EVENT_ACTION_UPDATE |
659                                           GESTURE_EVENT_ACTION_END | GESTURE_EVENT_ACTION_CANCEL,
660                                       column, onActionCallback);
661   // 将手势添加到column组件上,使column组件可以触发单指点击手势
662   gestureApi->addGestureToNode(column, TapGesture, ArkUI_GesturePriority::PARALLEL,
663                                           ArkUI_GestureMask::NORMAL_GESTURE_MASK);
664   ```