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 ```