1# 监听组件事件 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @jiangtao92--> 5<!--Designer: @piggyguy--> 6<!--Tester: @songyanhong--> 7<!--Adviser: @HelloCrease--> 8 9 10NDK接口针对UI组件的事件,提供了监听函数的方式。首先,可使用[addNodeEventReceiver](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#addnodeeventreceiver)函数添加组件事件的监听器,该监听器会监听该组件上发生的所有事件,例如:点击事件、焦点事件。然后,可使用[registerNodeEvent](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#registernodeevent)函数声明组件的哪些事件需要监听,NDK接口支持的事件范围通过[ArkUI_NodeEventType](../reference/apis-arkui/capi-native-node-h.md#arkui_nodeeventtype)枚举值定义。 11 12 13> **说明:** 14> - 事件注册需要声明[addNodeEventReceiver](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#addnodeeventreceiver)监听器注册和[registerNodeEvent](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#registernodeevent)事件类型,监听器只能监听已声明的事件。 15> 16> - 需要关注事件的反注册逻辑,如在组件销毁前调用[removeNodeEventReceiver](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#removenodeeventreceiver)移除事件监听器,[unregisterNodeEvent](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#unregisternodeevent)通知ArkUI框架已监听的事件不再需要监听。 17> 18> - [addNodeEventReceiver](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#addnodeeventreceiver)可以添加多个函数指针,每个函数指针都会在对应事件触发时触发,对应的[removeNodeEventReceiver](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#removenodeeventreceiver)需要传递对应的函数指针用于移除监听。 19> 20> - [registerNodeEventReceiver](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#registernodeeventreceiver)是全局监听函数,不同于[addNodeEventReceiver](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#addnodeeventreceiver),[registerNodeEventReceiver](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#registernodeeventreceiver)能够监听所有Native组件的事件触发,但只能传递一个函数指针,多次调用使用最后一次的函数指针进行回调,释放时使用[unregisterNodeEventReceiver](../reference/apis-arkui/capi-arkui-nativemodule-arkui-nativenodeapi-1.md#unregisternodeeventreceiver)进行释放。 21 22 23以下示例基于[接入ArkTS页面](ndk-access-the-arkts-page.md)章节,补充相关事件监听。详细代码请参考[完整示例](ndk-listen-to-component-events.md#完整示例)。 24 25 26- 事件注册和事件解注册 27 28 通过addNodeEventReceiver对节点绑定事件处理函数,接着通过调用registerNodeEvent注册对应的事件。 29 30 > 说明: 31 > 32 > 事件监听函数的入参ArkUI_NodeEvent* event的生命周期只在函数回调周期内生效,不推荐对该指针进行缓存或者进行异步处理。 33 34 ``` 35 ArkUI_NativeNodeAPI_1 *nodeAPI = nullptr; 36 OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nodeAPI); 37 void NodeEventReceiver(ArkUI_NodeEvent *event) { 38 // 设置对应的事件类型触发时进行的操作,如NODE_ON_CLICK_EVENT 39 }; 40 auto button = nodeAPI->createNode(ARKUI_NODE_BUTTON); 41 nodeAPI->addNodeEventReceiver(button, NodeEventReceiver); 42 nodeAPI->registerNodeEvent(button, NODE_ON_CLICK_EVENT, 0, nullptr); 43 ``` 44 详细的事件类型请参考[ArkUI_NodeEventType](../reference/apis-arkui/capi-native-node-h.md#arkui_nodeeventtype)。 45 46 通过unregisterNodeEvent解注册对应的事件类型,再通过removeNodeEventReceiver卸载事件处理函数。 47 48 ``` 49 nodeAPI->unregisterNodeEvent(button, NODE_ON_CLICK_EVENT); 50 nodeAPI->removeNodeEventReceiver(button, NodeEventReceiver); 51 ``` 52 53- 全局事件监听 54 55 使用registerNodeEventReceiver注册全局的事件处理函数,对事件进行统一的处理,结束后可使用unregisterNodeEventReceiver进行释放。 56 57 ```cpp 58 nodeAPI->registerNodeEventReceiver([](ArkUI_NodeEvent *event){ 59 auto *inputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event); 60 auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); 61 switch(eventType){ 62 case NODE_ON_CLICK_EVENT: { 63 // 触发点击事件所进行的操作 64 } 65 default: { 66 break; 67 } 68 } 69 }) 70 nodeAPI->unregisterNodeEventReceiver(); 71 ``` 72 73- 获取事件信息 74 75 ArkUI框架提供了[OH_ArkUI_NodeEvent_GetInputEvent()](../reference/apis-arkui/capi-native-node-h.md#oh_arkui_nodeevent_getinputevent)接口,用于从输入交互相关的组件事件(如NODE_ON_CLICK_EVENT、NODE_TOUCH_EVENT等,具体可参见每个枚举定义的说明)中获取基础事件对象。然后,可通过调用[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)等接口,从基础事件中获取更多信息。应用根据获取的事件信息,在事件执行过程中实现差异化交互逻辑。 76 77 ```cpp 78 // 注册click事件 79 const unsigned int LOG_PRINT_DOMAIN = 0xFF00; 80 nodeAPI->registerNodeEvent(button, NODE_ON_CLICK_EVENT, 0, nullptr); 81 // 设置组件事件的全局监听 82 nodeAPI->registerNodeEventReceiver([](ArkUI_NodeEvent *event) { 83 // 从组件事件中获取基础事件对象 84 auto *inputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event); 85 // 从组件事件获取事件类型 86 auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); 87 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfo", "inputEvent = %{public}p", inputEvent); 88 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfo", "eventType = %{public}d", eventType); 89 auto componentEvent = OH_ArkUI_NodeEvent_GetNodeComponentEvent(event); 90 // 获取组件事件中的数字类型数据 91 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfo", "componentEvent = %{public}p", 92 componentEvent); 93 // 获取触发该事件的组件对象 94 auto nodeHandle = OH_ArkUI_NodeEvent_GetNodeHandle(event); 95 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfo", "nodeHandle = %{public}p", nodeHandle); 96 // 根据eventType来区分事件类型,进行差异化处理,其他获取事件信息的接口也可类似方式来进行差异化的处理 97 switch (eventType) { 98 case NODE_ON_CLICK_EVENT: { 99 // 触发点击事件所进行的操作,从基础事件获取事件信息 100 auto x = OH_ArkUI_PointerEvent_GetX(inputEvent); 101 auto y = OH_ArkUI_PointerEvent_GetY(inputEvent); 102 auto displayX = OH_ArkUI_PointerEvent_GetDisplayX(inputEvent); 103 auto displayY = OH_ArkUI_PointerEvent_GetDisplayY(inputEvent); 104 auto windowX = OH_ArkUI_PointerEvent_GetWindowX(inputEvent); 105 auto windowY = OH_ArkUI_PointerEvent_GetWindowY(inputEvent); 106 auto pointerCount = OH_ArkUI_PointerEvent_GetPointerCount(inputEvent); 107 auto xByIndex = OH_ArkUI_PointerEvent_GetXByIndex(inputEvent, 0); 108 auto yByIndex = OH_ArkUI_PointerEvent_GetYByIndex(inputEvent, 0); 109 auto displayXByIndex = OH_ArkUI_PointerEvent_GetDisplayXByIndex(inputEvent, 0); 110 auto displayYByIndex = OH_ArkUI_PointerEvent_GetDisplayYByIndex(inputEvent, 0); 111 auto windowXByIndex = OH_ArkUI_PointerEvent_GetWindowXByIndex(inputEvent, 0); 112 auto windowYByIndex = OH_ArkUI_PointerEvent_GetWindowYByIndex(inputEvent, 0); 113 auto pointerId = OH_ArkUI_PointerEvent_GetPointerId(inputEvent, 0); 114 auto pressure = OH_ArkUI_PointerEvent_GetPressure(inputEvent, 0); 115 auto action = OH_ArkUI_UIInputEvent_GetAction(inputEvent); 116 auto eventTime = OH_ArkUI_UIInputEvent_GetEventTime(inputEvent); 117 auto sourceType = OH_ArkUI_UIInputEvent_GetSourceType(inputEvent); 118 auto type = OH_ArkUI_UIInputEvent_GetType(inputEvent); 119 std::string eventInfo = 120 "x: " + std::to_string(x) + ", y: " + std::to_string(y) + 121 ", displayX: " + std::to_string(displayX) + ", displayY: " + std::to_string(displayY) + 122 ", windowX: " + std::to_string(windowX) + ", windowY: " + std::to_string(windowY) + 123 ", pointerCount: " + std::to_string(pointerCount) + ", xByIndex: " + std::to_string(xByIndex) + 124 ", yByIndex: " + std::to_string(yByIndex) + 125 ", displayXByIndex: " + std::to_string(displayXByIndex) + 126 ", displayYByIndex: " + std::to_string(displayYByIndex) + 127 ", windowXByIndex: " + std::to_string(windowXByIndex) + 128 ", windowYByIndex: " + std::to_string(windowYByIndex) + 129 ", pointerId: " + std::to_string(pointerId) + ", pressure: " + std::to_string(pressure) + 130 ", action: " + std::to_string(action) + ", eventTime: " + std::to_string(eventTime) + 131 ", sourceType: " + std::to_string(sourceType) + ", type: " + std::to_string(type); 132 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfoOfCommonEvent", "eventInfo = %{public}s", 133 eventInfo.c_str()); 134 break; 135 } 136 default: { 137 break; 138 } 139 } 140 }); 141 nodeAPI->unregisterNodeEventReceiver(); 142 nodeAPI->unregisterNodeEvent(button, NODE_ON_CLICK_EVENT); 143 ``` 144 145 146- 深浅色变更事件 147 148 ArkUI开发框架在NDK接口提供了以组件为注册单位的系统深浅色变更事件,系统通过在深浅色变更时通知注册在组件上的回调,实现NDK侧的深浅色变更能力。 149 150 > **说明:** 151 > - 一个回调内可以自行设计多个组件的深浅色变更。 152 > - 同一组件仅能注册一个系统深浅变更回调。 153 > - 建议注册在页面内不会被销毁的节点,防止因节点销毁导致的回调失效。 154 155 ```cpp 156 const unsigned int LOG_PRINT_DOMAIN = 0xFF00; 157 struct ColorModeInfo { 158 const char* lightMsg; 159 const char* darkMsg; 160 }; 161 162 //注册回调函数 163 void onColorModeChange(ArkUI_SystemColorMode colorMode, void *userData) 164 { 165 ColorModeInfo* info = static_cast<ColorModeInfo*>(userData); 166 if (colorMode == ARKUI_SYSTEM_COLOR_MODE_LIGHT) { 167 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "Light mode: ", info->lightMsg); 168 } else if (colorMode == ARKUI_SYSTEM_COLOR_MODE_DARK) { 169 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "Dark mode: ", info->darkMsg); 170 } 171 } 172 173 ArkUI_NodeHandle testColorModeChange(ArkUI_NativeNodeAPI_1 *nodeAPI) { 174 ArkUI_NodeHandle text = nodeAPI->createNode(ARKUI_NODE_TEXT); 175 static ColorModeInfo info = {"现在是浅色模式", "现在是深色模式"}; 176 OH_ArkUI_RegisterSystemColorModeChangeEvent(text, &info, onColorModeChange); 177 178 ArkUI_AttributeItem itemstring = {nullptr, 0, ("人生得意须尽欢")}; 179 nodeAPI->setAttribute(text, NODE_TEXT_CONTENT, &itemstring); 180 181 return text; 182 } 183 ``` 184 185## 完整示例 186 1871. 在ArkUINode基类对象中实现通用事件注册逻辑。 188 189 ```c 190 // ArkUINode.h 191 // 提供通用属性和事件的封装。 192 193 #ifndef MYAPPLICATION_ARKUINODE_H 194 #define MYAPPLICATION_ARKUINODE_H 195 196 #include "ArkUIBaseNode.h" 197 #include "NativeModule.h" 198 199 #include <arkui/native_node.h> 200 #include <arkui/native_type.h> 201 202 namespace NativeModule { 203 204 class ArkUINode : public ArkUIBaseNode { 205 public: 206 explicit ArkUINode(ArkUI_NodeHandle handle) : ArkUIBaseNode(handle) { 207 nativeModule_ = NativeModuleInstance::GetInstance()->GetNativeNodeAPI(); 208 // 事件触发时需要通过函数获取对应的事件对象,这边通过设置节点自定义数据将封装类指针保持在组件上,方便后续事件分发。 209 nativeModule_->setUserData(handle_, this); 210 // 注册节点监听事件接受器。 211 nativeModule_->addNodeEventReceiver(handle_, ArkUINode::NodeEventReceiver); 212 } 213 214 ~ArkUINode() override { 215 if (onClick_) { 216 nativeModule_->unregisterNodeEvent(handle_, NODE_ON_CLICK_EVENT); 217 } 218 if (onTouch_) { 219 nativeModule_->unregisterNodeEvent(handle_, NODE_TOUCH_EVENT); 220 } 221 if (onDisappear_) { 222 nativeModule_->unregisterNodeEvent(handle_, NODE_EVENT_ON_DISAPPEAR); 223 } 224 if (onAppear_) { 225 nativeModule_->unregisterNodeEvent(handle_, NODE_EVENT_ON_APPEAR); 226 } 227 nativeModule_->removeNodeEventReceiver(handle_, ArkUINode::NodeEventReceiver); 228 } 229 230 void SetWidth(float width) { 231 assert(handle_); 232 ArkUI_NumberValue value[] = {{.f32 = width}}; 233 ArkUI_AttributeItem item = {value, 1}; 234 nativeModule_->setAttribute(handle_, NODE_WIDTH, &item); 235 } 236 void SetPercentWidth(float percent) { 237 assert(handle_); 238 ArkUI_NumberValue value[] = {{.f32 = percent}}; 239 ArkUI_AttributeItem item = {value, 1}; 240 nativeModule_->setAttribute(handle_, NODE_WIDTH_PERCENT, &item); 241 } 242 void SetHeight(float height) { 243 assert(handle_); 244 ArkUI_NumberValue value[] = {{.f32 = height}}; 245 ArkUI_AttributeItem item = {value, 1}; 246 nativeModule_->setAttribute(handle_, NODE_HEIGHT, &item); 247 } 248 void SetPercentHeight(float percent) { 249 assert(handle_); 250 ArkUI_NumberValue value[] = {{.f32 = percent}}; 251 ArkUI_AttributeItem item = {value, 1}; 252 nativeModule_->setAttribute(handle_, NODE_HEIGHT_PERCENT, &item); 253 } 254 void SetBackgroundColor(uint32_t color) { 255 assert(handle_); 256 ArkUI_NumberValue value[] = {{.u32 = color}}; 257 ArkUI_AttributeItem item = {value, 1}; 258 nativeModule_->setAttribute(handle_, NODE_BACKGROUND_COLOR, &item); 259 } 260 // 处理通用事件。 261 void RegisterOnClick(const std::function<void(ArkUI_NodeEvent *event)> &onClick) { 262 assert(handle_); 263 onClick_ = onClick; 264 // 注册点击事件。 265 nativeModule_->registerNodeEvent(handle_, NODE_ON_CLICK_EVENT, 0, nullptr); 266 } 267 268 void RegisterOnTouch(const std::function<void(int32_t type, float x, float y)> &onTouch) { 269 assert(handle_); 270 onTouch_ = onTouch; 271 // 注册触碰事件。 272 nativeModule_->registerNodeEvent(handle_, NODE_TOUCH_EVENT, 0, nullptr); 273 } 274 275 void RegisterOnDisappear(const std::function<void()> &onDisappear) { 276 assert(handle_); 277 onDisappear_ = onDisappear; 278 // 注册卸载事件。 279 nativeModule_->registerNodeEvent(handle_, NODE_EVENT_ON_DISAPPEAR, 0, nullptr); 280 } 281 282 void RegisterOnAppear(const std::function<void()> &onAppear) { 283 assert(handle_); 284 onAppear_ = onAppear; 285 // 注册挂载事件。 286 nativeModule_->registerNodeEvent(handle_, NODE_EVENT_ON_APPEAR, 0, nullptr); 287 } 288 289 protected: 290 // 事件监听器函数指针。 291 static void NodeEventReceiver(ArkUI_NodeEvent *event) { 292 // 获取事件发生的UI组件对象。 293 auto nodeHandle = OH_ArkUI_NodeEvent_GetNodeHandle(event); 294 // 获取保持在UI组件对象中的自定义数据,返回封装类指针。 295 auto *node = reinterpret_cast<ArkUINode *>( 296 NativeModuleInstance::GetInstance()->GetNativeNodeAPI()->getUserData(nodeHandle)); 297 // 基于封装类实例对象处理事件。 298 node->ProcessNodeEvent(event); 299 } 300 void ProcessNodeEvent(ArkUI_NodeEvent *event) { 301 auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); 302 switch (eventType) { 303 case NODE_ON_CLICK_EVENT: { 304 if (onClick_) { 305 onClick_(event); 306 } 307 break; 308 } 309 case NODE_TOUCH_EVENT: { 310 if (onTouch_) { 311 auto *uiInputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event); 312 float x = OH_ArkUI_PointerEvent_GetX(uiInputEvent); 313 float y = OH_ArkUI_PointerEvent_GetY(uiInputEvent); 314 auto type = OH_ArkUI_UIInputEvent_GetAction(uiInputEvent); 315 onTouch_(type, x, y); 316 } 317 } 318 case NODE_EVENT_ON_DISAPPEAR: { 319 if (onDisappear_) { 320 onDisappear_(); 321 } 322 break; 323 } 324 case NODE_EVENT_ON_APPEAR: { 325 if (onAppear_) { 326 onAppear_(); 327 } 328 break; 329 } 330 default: { 331 // 组件特有事件交给子类处理 332 OnNodeEvent(event); 333 } 334 } 335 } 336 337 virtual void OnNodeEvent(ArkUI_NodeEvent *event) {} 338 339 void OnAddChild(const std::shared_ptr<ArkUIBaseNode> &child) override { 340 nativeModule_->addChild(handle_, child->GetHandle()); 341 } 342 343 void OnRemoveChild(const std::shared_ptr<ArkUIBaseNode> &child) override { 344 nativeModule_->removeChild(handle_, child->GetHandle()); 345 } 346 347 void OnInsertChild(const std::shared_ptr<ArkUIBaseNode> &child, int32_t index) override { 348 nativeModule_->insertChildAt(handle_, child->GetHandle(), index); 349 } 350 351 private: 352 std::function<void(ArkUI_NodeEvent *event)> onClick_; 353 std::function<void()> onDisappear_; 354 std::function<void()> onAppear_; 355 std::function<void(int32_t type, float x, float y)> onTouch_; 356 }; 357 } // namespace NativeModule 358 359 #endif // MYAPPLICATION_ARKUINODE_H 360 361 ``` 362 3632. 在ArkUIListNode对象中实现列表事件注册逻辑。 364 ```c 365 // ArkUIListNode.h 366 // 列表封装类对象 367 368 #ifndef MYAPPLICATION_ARKUILISTNODE_H 369 #define MYAPPLICATION_ARKUILISTNODE_H 370 371 #include "ArkUINode.h" 372 #include <hilog/log.h> 373 374 namespace NativeModule { 375 class ArkUIListNode : public ArkUINode { 376 public: 377 ArkUIListNode() 378 : ArkUINode((NativeModuleInstance::GetInstance()->GetNativeNodeAPI())->createNode(ARKUI_NODE_LIST)) {} 379 380 ~ArkUIListNode() override { nativeModule_->unregisterNodeEvent(handle_, NODE_LIST_ON_SCROLL_INDEX); } 381 382 void SetScrollBarState(bool isShow) { 383 assert(handle_); 384 ArkUI_ScrollBarDisplayMode displayMode = 385 isShow ? ARKUI_SCROLL_BAR_DISPLAY_MODE_ON : ARKUI_SCROLL_BAR_DISPLAY_MODE_OFF; 386 ArkUI_NumberValue value[] = {{.i32 = displayMode}}; 387 ArkUI_AttributeItem item = {value, 1}; 388 nativeModule_->setAttribute(handle_, NODE_SCROLL_BAR_DISPLAY_MODE, &item); 389 } 390 391 // 注册列表相关事件。 392 void RegisterOnScrollIndex(const std::function<void(int32_t index)> &onScrollIndex) { 393 assert(handle_); 394 onScrollIndex_ = onScrollIndex; 395 nativeModule_->registerNodeEvent(handle_, NODE_LIST_ON_SCROLL_INDEX, 0, nullptr); 396 } 397 398 protected: 399 // 处理List相关事件。 400 void OnNodeEvent(ArkUI_NodeEvent *event) override { 401 auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); 402 switch (eventType) { 403 case NODE_LIST_ON_SCROLL_INDEX: { 404 auto index = OH_ArkUI_NodeEvent_GetNodeComponentEvent(event)->data[0]; 405 if (onScrollIndex_) { 406 onScrollIndex_(index.i32); 407 } 408 } 409 default: { 410 } 411 } 412 } 413 414 private: 415 std::function<void(int32_t index)> onScrollIndex_; 416 }; 417 } // namespace NativeModule 418 419 #endif // MYAPPLICATION_ARKUILISTNODE_H 420 ``` 421 4223. 添加相关事件。 423 ```c 424 // TextListExample.h 425 // 文本列表示例。 426 427 #ifndef MYAPPLICATION_NORMALTEXTLISTEXAMPLE_H 428 #define MYAPPLICATION_NORMALTEXTLISTEXAMPLE_H 429 430 #include "ArkUIBaseNode.h" 431 #include "ArkUIListItemNode.h" 432 #include "ArkUIListNode.h" 433 #include "ArkUITextNode.h" 434 #include <hilog/log.h> 435 436 const unsigned int LOG_PRINT_DOMAIN = 0xFF00; 437 438 namespace NativeModule { 439 440 std::shared_ptr<ArkUIBaseNode> CreateTextListExample() { 441 // 创建组件并挂载 442 // 1:创建List组件。 443 auto list = std::make_shared<ArkUIListNode>(); 444 list->SetPercentWidth(1); 445 list->SetPercentHeight(1); 446 // 2:创建ListItem子组件并挂载到List上。 447 for (int32_t i = 0; i < 30; ++i) { 448 auto listItem = std::make_shared<ArkUIListItemNode>(); 449 auto textNode = std::make_shared<ArkUITextNode>(); 450 textNode->SetTextContent(std::to_string(i)); 451 textNode->SetFontSize(16); 452 textNode->SetPercentWidth(1); 453 textNode->SetHeight(100); 454 textNode->SetBackgroundColor(0xFFfffacd); 455 textNode->SetTextAlign(ARKUI_TEXT_ALIGNMENT_CENTER); 456 listItem->AddChild(textNode); 457 // 列表项注册点击事件。 458 auto onClick = [](ArkUI_NodeEvent *event) { 459 // 从组件事件中获取基础事件对象 460 auto *inputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event); 461 if (inputEvent == nullptr) { 462 return; 463 } 464 // 从组件事件获取事件类型 465 auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); 466 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfo", "inputEvent = %{public}p", inputEvent); 467 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfo", "eventType = %{public}d", eventType); 468 auto componentEvent = OH_ArkUI_NodeEvent_GetNodeComponentEvent(event); 469 // 获取组件事件中的数字类型数据 470 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfo", "componentEvent = %{public}p", 471 componentEvent); 472 // 获取触发该事件的组件对象 473 auto nodeHandle = OH_ArkUI_NodeEvent_GetNodeHandle(event); 474 if (nodeHandle == nullptr) { 475 return; 476 } 477 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfo", "nodeHandle = %{public}p", nodeHandle); 478 // 根据eventType来区分事件类型,进行差异化处理,其他获取事件信息的接口也可类似方式来进行差异化的处理 479 switch (eventType) { 480 case NODE_ON_CLICK_EVENT: { 481 // 触发点击事件所进行的操作,从基础事件获取事件信息 482 auto x = OH_ArkUI_PointerEvent_GetX(inputEvent); 483 auto y = OH_ArkUI_PointerEvent_GetY(inputEvent); 484 auto displayX = OH_ArkUI_PointerEvent_GetDisplayX(inputEvent); 485 auto displayY = OH_ArkUI_PointerEvent_GetDisplayY(inputEvent); 486 auto windowX = OH_ArkUI_PointerEvent_GetWindowX(inputEvent); 487 auto windowY = OH_ArkUI_PointerEvent_GetWindowY(inputEvent); 488 auto pointerCount = OH_ArkUI_PointerEvent_GetPointerCount(inputEvent); 489 auto xByIndex = OH_ArkUI_PointerEvent_GetXByIndex(inputEvent, 0); 490 auto yByIndex = OH_ArkUI_PointerEvent_GetYByIndex(inputEvent, 0); 491 auto displayXByIndex = OH_ArkUI_PointerEvent_GetDisplayXByIndex(inputEvent, 0); 492 auto displayYByIndex = OH_ArkUI_PointerEvent_GetDisplayYByIndex(inputEvent, 0); 493 auto windowXByIndex = OH_ArkUI_PointerEvent_GetWindowXByIndex(inputEvent, 0); 494 auto windowYByIndex = OH_ArkUI_PointerEvent_GetWindowYByIndex(inputEvent, 0); 495 auto pointerId = OH_ArkUI_PointerEvent_GetPointerId(inputEvent, 0); 496 auto pressure = OH_ArkUI_PointerEvent_GetPressure(inputEvent, 0); 497 auto action = OH_ArkUI_UIInputEvent_GetAction(inputEvent); 498 auto eventTime = OH_ArkUI_UIInputEvent_GetEventTime(inputEvent); 499 auto sourceType = OH_ArkUI_UIInputEvent_GetSourceType(inputEvent); 500 auto type = OH_ArkUI_UIInputEvent_GetType(inputEvent); 501 std::string eventInfo = 502 "x: " + std::to_string(x) + ", y: " + std::to_string(y) + 503 ", displayX: " + std::to_string(displayX) + ", displayY: " + std::to_string(displayY) + 504 ", windowX: " + std::to_string(windowX) + ", windowY: " + std::to_string(windowY) + 505 ", pointerCount: " + std::to_string(pointerCount) + ", xByIndex: " + std::to_string(xByIndex) + 506 ", yByIndex: " + std::to_string(yByIndex) + 507 ", displayXByIndex: " + std::to_string(displayXByIndex) + 508 ", displayYByIndex: " + std::to_string(displayYByIndex) + 509 ", windowXByIndex: " + std::to_string(windowXByIndex) + 510 ", windowYByIndex: " + std::to_string(windowYByIndex) + 511 ", pointerId: " + std::to_string(pointerId) + ", pressure: " + std::to_string(pressure) + 512 ", action: " + std::to_string(action) + ", eventTime: " + std::to_string(eventTime) + 513 ", sourceType: " + std::to_string(sourceType) + ", type: " + std::to_string(type); 514 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "eventInfoOfCommonEvent", 515 "eventInfo = %{public}s", eventInfo.c_str()); 516 } 517 default: { 518 break; 519 } 520 } 521 }; 522 listItem->RegisterOnClick(onClick); 523 list->AddChild(listItem); 524 } 525 // 3:注册List相关监听事件. 526 list->RegisterOnScrollIndex([](int32_t index) { OH_LOG_INFO(LOG_APP, "on list scroll index: %{public}d", index); }); 527 // 4: 注册挂载事件。 528 list->RegisterOnAppear([]() { OH_LOG_INFO(LOG_APP, "on list mount to tree"); }); 529 // 5: 注册卸载事件。 530 list->RegisterOnDisappear([]() { OH_LOG_INFO(LOG_APP, "on list unmount from tree"); }); 531 return list; 532 } 533 } // namespace NativeModule 534 535 #endif // MYAPPLICATION_NORMALTEXTLISTEXAMPLE_H 536 537 ``` 538