绑定基础输入事件
NDK接口提供了监听和处理基础输入事件的能力,可绑定点击事件(NODE_ON_CLICK_EVENT)、触摸事件(NODE_TOUCH_EVENT)、鼠标事件(NODE_ON_MOUSE)、悬浮事件(NODE_ON_HOVER_EVENT)、轴事件(NODE_ON_AXIS)、按键事件(NODE_ON_KEY_EVENT),然后通过事件接收器中的回调函数获取事件的详细信息。
以下示例均需基于接入ArkTS页面章节,详细代码请参考完整示例。
点击事件
点击事件在用户点击组件时触发,可获取点击位置、触摸点数量、指针ID、压力值等信息。可对节点绑定如下处理函数。
// 处理点击事件
void HandleClickEvent(ArkUI_UIInputEvent *inputEvent)
{
auto pos = GetPointerPosition(inputEvent);
auto baseInfo = GetBaseEventInfo(inputEvent);
auto pointerCount = OH_ArkUI_PointerEvent_GetPointerCount(inputEvent);
auto pointerId = OH_ArkUI_PointerEvent_GetPointerId(inputEvent, 0);
auto pressure = OH_ArkUI_PointerEvent_GetPressure(inputEvent, 0);
// 通过索引获取指针位置信息(支持多点触控场景)
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);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]",
"[%{public}s] Click: x=%{public}f, y=%{public}f, displayX=%{public}f, displayY=%{public}f, "
"windowX=%{public}f, windowY=%{public}f, xByIndex=%{public}f, yByIndex=%{public}f, "
"displayXByIndex=%{public}f, displayYByIndex=%{public}f, windowXByIndex=%{public}f, "
"windowYByIndex=%{public}f, pointerCount=%{public}d, pointerId=%{public}d, "
"pressure=%{public}f, action=%{public}d, eventTime=%{public}lld, sourceType=%{public}d, type=%{public}d",
eventName_.c_str(), pos.x, pos.y, pos.displayX, pos.displayY, pos.windowX, pos.windowY,
xByIndex, yByIndex, displayXByIndex, displayYByIndex, windowXByIndex, windowYByIndex,
pointerCount, pointerId, pressure, baseInfo.action, baseInfo.eventTime,
baseInfo.sourceType, baseInfo.type);
}
从API version 18开始,新增NODE_ON_CLICK_EVENT枚举。节点自身可以注册NODE_ON_CLICK_EVENT事件监听,以响应上述处理函数。
nativeModule_->registerNodeEvent(handle_, NODE_ON_CLICK_EVENT, 0, this);
触摸事件
触摸事件在用户触摸屏幕时触发,除了点击事件的信息外,还可获取触摸区域宽度和高度。可对节点绑定如下处理函数。
// 处理触摸事件
void HandleTouchEvent(ArkUI_UIInputEvent *inputEvent)
{
auto pos = GetPointerPosition(inputEvent);
auto baseInfo = GetBaseEventInfo(inputEvent);
auto pointerCount = OH_ArkUI_PointerEvent_GetPointerCount(inputEvent);
auto pointerId = OH_ArkUI_PointerEvent_GetPointerId(inputEvent, 0);
auto pressure = OH_ArkUI_PointerEvent_GetPressure(inputEvent, 0);
auto touchAreaWidth = OH_ArkUI_PointerEvent_GetTouchAreaWidth(inputEvent, 0);
auto touchAreaHeight = OH_ArkUI_PointerEvent_GetTouchAreaHeight(inputEvent, 0);
// 通过索引获取指针位置信息(支持多点触控场景)
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);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]",
"[%{public}s] Touch: x=%{public}f, y=%{public}f, displayX=%{public}f, displayY=%{public}f, "
"windowX=%{public}f, windowY=%{public}f, xByIndex=%{public}f, yByIndex=%{public}f, "
"displayXByIndex=%{public}f, displayYByIndex=%{public}f, windowXByIndex=%{public}f, "
"windowYByIndex=%{public}f, pointerCount=%{public}d, pointerId=%{public}d, "
"pressure=%{public}f, touchAreaWidth=%{public}f, touchAreaHeight=%{public}f, "
"action=%{public}d, eventTime=%{public}lld, sourceType=%{public}d, type=%{public}d",
eventName_.c_str(), pos.x, pos.y, pos.displayX, pos.displayY, pos.windowX, pos.windowY,
xByIndex, yByIndex, displayXByIndex, displayYByIndex, windowXByIndex, windowYByIndex,
pointerCount, pointerId, pressure, touchAreaWidth, touchAreaHeight, baseInfo.action,
baseInfo.eventTime, baseInfo.sourceType, baseInfo.type);
}
节点自身需要注册NODE_TOUCH_EVENT事件监听,以响应上述处理函数。
nativeModule_->registerNodeEvent(handle_, NODE_TOUCH_EVENT, 0, this);
鼠标事件
鼠标事件在使用鼠标操作时触发,可获取鼠标按键类型、鼠标动作类型、滚轮移动增量等信息。可对节点绑定如下处理函数。
// 处理鼠标事件
void HandleMouseEvent(ArkUI_UIInputEvent *inputEvent)
{
auto pos = GetPointerPosition(inputEvent);
auto baseInfo = GetBaseEventInfo(inputEvent);
auto button = OH_ArkUI_MouseEvent_GetMouseButton(inputEvent);
auto mouseAction = OH_ArkUI_MouseEvent_GetMouseAction(inputEvent);
auto rawDeltaX = OH_ArkUI_MouseEvent_GetRawDeltaX(inputEvent);
auto rawDeltaY = OH_ArkUI_MouseEvent_GetRawDeltaY(inputEvent);
auto buttonCount = GetPressedButtonsCount(inputEvent);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]",
"[%{public}s] Mouse: x=%{public}f, y=%{public}f, displayX=%{public}f, displayY=%{public}f, "
"windowX=%{public}f, windowY=%{public}f, button=%{public}d, mouseAction=%{public}d, "
"pressedButtonsCount=%{public}d, rawDeltaX=%{public}f, rawDeltaY=%{public}f, "
"action=%{public}d, eventTime=%{public}lld, sourceType=%{public}d, type=%{public}d",
eventName_.c_str(), pos.x, pos.y, pos.displayX, pos.displayY, pos.windowX, pos.windowY,
button, mouseAction, buttonCount, rawDeltaX, rawDeltaY, baseInfo.action,
baseInfo.eventTime, baseInfo.sourceType, baseInfo.type);
}
节点自身需要注册NODE_ON_MOUSE事件监听,以响应上述处理函数。
nativeModule_->registerNodeEvent(handle_, NODE_ON_MOUSE, 0, this);
悬浮事件
悬浮事件在鼠标指针移至组件上方或远离组件时触发,可获取悬浮状态。可对节点绑定如下处理函数。
// 处理悬浮事件
void HandleHoverEvent(ArkUI_UIInputEvent *inputEvent)
{
auto pos = GetPointerPosition(inputEvent);
auto baseInfo = GetBaseEventInfo(inputEvent);
auto isHovered = OH_ArkUI_HoverEvent_IsHovered(inputEvent);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]",
"[%{public}s] Hover: x=%{public}f, y=%{public}f, displayX=%{public}f, displayY=%{public}f, "
"windowX=%{public}f, windowY=%{public}f, isHovered=%{public}d, action=%{public}d, "
"eventTime=%{public}lld, sourceType=%{public}d, type=%{public}d",
eventName_.c_str(), pos.x, pos.y, pos.displayX, pos.displayY, pos.windowX, pos.windowY,
isHovered, baseInfo.action, baseInfo.eventTime, baseInfo.sourceType, baseInfo.type);
}
从API version 17开始,新增NODE_ON_HOVER_EVENT枚举。节点自身可以注册NODE_ON_HOVER_EVENT事件监听,以响应上述处理函数。
nativeModule_->registerNodeEvent(handle_, NODE_ON_HOVER_EVENT, 0, this);
轴事件
轴事件通过鼠标滚轮、游戏摇杆等设备触发,可获取轴动作类型、垂直轴值、水平轴值、缩放比例、滚动步长等信息。可对节点绑定如下处理函数。
// 处理轴事件
void HandleAxisEvent(ArkUI_UIInputEvent *inputEvent)
{
auto baseInfo = GetBaseEventInfo(inputEvent);
auto axisAction = OH_ArkUI_AxisEvent_GetAxisAction(inputEvent);
auto verticalAxis = OH_ArkUI_AxisEvent_GetVerticalAxisValue(inputEvent);
auto horizontalAxis = OH_ArkUI_AxisEvent_GetHorizontalAxisValue(inputEvent);
auto pinchAxisScale = OH_ArkUI_AxisEvent_GetPinchAxisScaleValue(inputEvent);
auto scrollStep = OH_ArkUI_AxisEvent_GetScrollStep(inputEvent);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]",
"[%{public}s] Axis: axisAction=%{public}d, verticalAxis=%{public}f, horizontalAxis=%{public}f, "
"pinchAxisScale=%{public}f, scrollStep=%{public}d, action=%{public}d, "
"eventTime=%{public}lld, sourceType=%{public}d, type=%{public}d",
eventName_.c_str(), axisAction, verticalAxis, horizontalAxis, pinchAxisScale, scrollStep,
baseInfo.action, baseInfo.eventTime, baseInfo.sourceType, baseInfo.type);
}
从API version 17开始,新增NODE_ON_AXIS枚举。节点自身可以注册NODE_ON_AXIS事件监听,以响应上述处理函数。
nativeModule_->registerNodeEvent(handle_, NODE_ON_AXIS, 0, this);
按键事件
按键事件在用户按下或释放键盘按键时触发,可获取按键类型、按键动作、按下的键、修饰键状态、设备ID等信息。组件需要先获取焦点才能响应按键事件。可对节点绑定如下处理函数。
// 处理按键事件
void HandleKeyEvent(ArkUI_UIInputEvent *inputEvent)
{
auto type = OH_ArkUI_KeyEvent_GetType(inputEvent);
auto baseInfo = GetBaseEventInfo(inputEvent);
auto deviceId = OH_ArkUI_UIInputEvent_GetDeviceId(inputEvent);
auto keyInfo = GetKeyInfo(inputEvent);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]",
"[%{public}s] Key: type=%{public}d, action=%{public}d, pressedKey=%{public}d, "
"modifierKeys=%{public}llu, deviceId=%{public}d, eventTime=%{public}lld, sourceType=%{public}d",
eventName_.c_str(), type, baseInfo.action, keyInfo.pressedKey, keyInfo.modifierKeys,
deviceId, baseInfo.eventTime, baseInfo.sourceType);
}
设置节点为可聚焦,并绑定点击事件,在点击时请求焦点。同时节点自身需要注册NODE_ON_KEY_EVENT事件监听,以响应上述处理函数。
// 设置为可聚焦,以便接收按键事件
ArkUI_NumberValue focusable[] = {1};
ArkUI_AttributeItem focusableItem = {focusable, 1};
nativeModule_->setAttribute(handle_, NODE_FOCUSABLE, &focusableItem);
// 注册点击事件,点击时请求焦点
nativeModule_->registerNodeEvent(handle_, NODE_ON_CLICK_EVENT, 0, this);
// 注册按键事件
nativeModule_->registerNodeEvent(handle_, NODE_ON_KEY_EVENT, 0, this);
完整示例
-
定义基础输入事件的数据结构。
// InputEventTypes.h // 输入事件相关的类型定义和辅助函数 #ifndef MYAPPLICATION_INPUTEVENTTYPES_H #define MYAPPLICATION_INPUTEVENTTYPES_H #include <cstdint> namespace NativeModule { // 基础事件信息结构体 struct BaseEventInfo { int32_t action; int64_t eventTime; int32_t sourceType; int32_t type; }; // 指针坐标信息结构体 struct PointerPosition { float x; float y; float displayX; float displayY; float windowX; float windowY; }; // 按键信息结构体 struct KeyInfo { int32_t pressedKey; uint64_t modifierKeys; }; } // namespace NativeModule #endif // MYAPPLICATION_INPUTEVENTTYPES_H -
注册各种基础输入事件并实现相应事件的监听。
// NormalTextListExample.h // 输入事件示例,展示基础输入事件的绑定和处理 #ifndef MYAPPLICATION_NORMALTEXTLISTEXAMPLE_H #define MYAPPLICATION_NORMALTEXTLISTEXAMPLE_H #include "ArkUIBaseNode.h" #include "ArkUIListItemNode.h" #include "ArkUIListNode.h" #include "ArkUITextNode.h" #include "InputEventTypes.h" #include <arkui/native_key_event.h> #include <hilog/log.h> #include <string> namespace NativeModule { // 常量定义 const unsigned int LOG_PRINT_DOMAIN = 0xF811; const unsigned int ITEM_HEIGHT = 100; const unsigned int FONT_SIZE = 16; // 自定义列表项类,用于处理不同类型的输入事件 class InputEventListItem : public ArkUIListItemNode { public: enum EventType { CLICK_EVENT, TOUCH_EVENT, MOUSE_EVENT, HOVER_EVENT, AXIS_EVENT, KEY_EVENT }; InputEventListItem(const std::string& eventName, uint32_t bgColor, EventType eventType) : eventName_(eventName), eventType_(eventType) { SetPercentWidth(1); SetHeight(ITEM_HEIGHT); SetBackgroundColor(bgColor); auto textNode = std::make_shared<ArkUITextNode>(); textNode->SetTextContent(eventName); textNode->SetFontSize(FONT_SIZE); textNode->SetFontColor(0xFFFFFFFF); textNode->SetTextAlign(ARKUI_TEXT_ALIGNMENT_CENTER); textNode->SetPercentWidth(1); AddChild(textNode); // 注册事件监听器 RegisterEventReceiver(); } private: // 注册事件接收器和回调 void RegisterEventReceiver() { if (!handle_) { return; } nativeModule_->addNodeEventReceiver(handle_, [](ArkUI_NodeEvent *event) { auto *item = static_cast<InputEventListItem*>(OH_ArkUI_NodeEvent_GetUserData(event)); if (item) { item->HandleEvent(event); } }); RegisterEventByType(); } // 根据事件类型注册具体事件 void RegisterEventByType() { switch (eventType_) { case CLICK_EVENT: RegisterClickEvent(); break; case TOUCH_EVENT: RegisterTouchEvent(); break; case MOUSE_EVENT: RegisterMouseEvent(); break; case HOVER_EVENT: RegisterHoverEvent(); break; case AXIS_EVENT: RegisterAxisEvent(); break; case KEY_EVENT: RegisterKeyEvent(); break; } } // 注册点击事件 void RegisterClickEvent() { nativeModule_->registerNodeEvent(handle_, NODE_ON_CLICK_EVENT, 0, this); } // 注册触摸事件 void RegisterTouchEvent() { nativeModule_->registerNodeEvent(handle_, NODE_TOUCH_EVENT, 0, this); } // 注册鼠标事件 void RegisterMouseEvent() { // 鼠标事件(点击、移动、释放等) nativeModule_->registerNodeEvent(handle_, NODE_ON_MOUSE, 0, this); } // 注册悬浮事件 void RegisterHoverEvent() { nativeModule_->registerNodeEvent(handle_, NODE_ON_HOVER_EVENT, 0, this); } // 注册轴事件 void RegisterAxisEvent() { // 轴事件:鼠标滚轮滚动时触发 nativeModule_->registerNodeEvent(handle_, NODE_ON_AXIS, 0, this); } // 注册按键事件 void RegisterKeyEvent() { // 设置为可聚焦,以便接收按键事件 ArkUI_NumberValue focusable[] = {1}; ArkUI_AttributeItem focusableItem = {focusable, 1}; nativeModule_->setAttribute(handle_, NODE_FOCUSABLE, &focusableItem); // 注册点击事件,点击时请求焦点 nativeModule_->registerNodeEvent(handle_, NODE_ON_CLICK_EVENT, 0, this); // 注册按键事件 nativeModule_->registerNodeEvent(handle_, NODE_ON_KEY_EVENT, 0, this); } // 事件分发处理 void HandleEvent(ArkUI_NodeEvent *event) { auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); auto *inputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event); auto uiType = OH_ArkUI_UIInputEvent_GetType(inputEvent); DispatchEvent(eventType, uiType, inputEvent); } // 根据事件类型分发到具体处理函数 void DispatchEvent(int32_t eventType, int32_t uiType, ArkUI_UIInputEvent *inputEvent) { switch (eventType_) { case CLICK_EVENT: if (eventType == NODE_ON_CLICK_EVENT) { HandleClickEvent(inputEvent); } break; case TOUCH_EVENT: if (eventType == NODE_TOUCH_EVENT && uiType == ARKUI_UIINPUTEVENT_TYPE_TOUCH) { HandleTouchEvent(inputEvent); } break; case MOUSE_EVENT: // 鼠标事件(点击、移动、释放等) if (eventType == NODE_ON_MOUSE && uiType == ARKUI_UIINPUTEVENT_TYPE_MOUSE) { HandleMouseEvent(inputEvent); } break; case HOVER_EVENT: if (eventType == NODE_ON_HOVER_EVENT) { HandleHoverEvent(inputEvent); } break; case AXIS_EVENT: // 鼠标滚轮滚动或触控板手势时触发 if (eventType == NODE_ON_AXIS && uiType == ARKUI_UIINPUTEVENT_TYPE_AXIS) { HandleAxisEvent(inputEvent); } break; case KEY_EVENT: if (eventType == NODE_ON_CLICK_EVENT) { // 点击时请求焦点 ArkUI_NumberValue requestFocus[] = {1}; ArkUI_AttributeItem requestFocusItem = {requestFocus, 1}; nativeModule_->setAttribute(handle_, NODE_FOCUS_STATUS, &requestFocusItem); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]", "[%{public}s] Focus requested", eventName_.c_str()); } else if (eventType == NODE_ON_KEY_EVENT && uiType == ARKUI_UIINPUTEVENT_TYPE_KEY) { // 处理按键事件 HandleKeyEvent(inputEvent); } break; } } // 获取基础事件信息 BaseEventInfo GetBaseEventInfo(ArkUI_UIInputEvent *inputEvent) { BaseEventInfo info; info.action = OH_ArkUI_UIInputEvent_GetAction(inputEvent); info.eventTime = OH_ArkUI_UIInputEvent_GetEventTime(inputEvent); info.sourceType = OH_ArkUI_UIInputEvent_GetSourceType(inputEvent); info.type = OH_ArkUI_UIInputEvent_GetType(inputEvent); return info; } // 获取事件位置信息 PointerPosition GetPointerPosition(ArkUI_UIInputEvent *inputEvent) { PointerPosition pos; pos.x = OH_ArkUI_PointerEvent_GetX(inputEvent); pos.y = OH_ArkUI_PointerEvent_GetY(inputEvent); pos.displayX = OH_ArkUI_PointerEvent_GetDisplayX(inputEvent); pos.displayY = OH_ArkUI_PointerEvent_GetDisplayY(inputEvent); pos.windowX = OH_ArkUI_PointerEvent_GetWindowX(inputEvent); pos.windowY = OH_ArkUI_PointerEvent_GetWindowY(inputEvent); return pos; } // 打印事件位置信息 void LogPointerPosition(const char *eventName, const PointerPosition &pos) { OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]", "[%{public}s] x=%{public}f, y=%{public}f, displayX=%{public}f, displayY=%{public}f, " "windowX=%{public}f, windowY=%{public}f", eventName, pos.x, pos.y, pos.displayX, pos.displayY, pos.windowX, pos.windowY); } // 处理点击事件 void HandleClickEvent(ArkUI_UIInputEvent *inputEvent) { auto pos = GetPointerPosition(inputEvent); auto baseInfo = GetBaseEventInfo(inputEvent); auto pointerCount = OH_ArkUI_PointerEvent_GetPointerCount(inputEvent); auto pointerId = OH_ArkUI_PointerEvent_GetPointerId(inputEvent, 0); auto pressure = OH_ArkUI_PointerEvent_GetPressure(inputEvent, 0); // 通过索引获取指针位置信息(支持多点触控场景) 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); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]", "[%{public}s] Click: x=%{public}f, y=%{public}f, displayX=%{public}f, displayY=%{public}f, " "windowX=%{public}f, windowY=%{public}f, xByIndex=%{public}f, yByIndex=%{public}f, " "displayXByIndex=%{public}f, displayYByIndex=%{public}f, windowXByIndex=%{public}f, " "windowYByIndex=%{public}f, pointerCount=%{public}d, pointerId=%{public}d, " "pressure=%{public}f, action=%{public}d, eventTime=%{public}lld, sourceType=%{public}d, type=%{public}d", eventName_.c_str(), pos.x, pos.y, pos.displayX, pos.displayY, pos.windowX, pos.windowY, xByIndex, yByIndex, displayXByIndex, displayYByIndex, windowXByIndex, windowYByIndex, pointerCount, pointerId, pressure, baseInfo.action, baseInfo.eventTime, baseInfo.sourceType, baseInfo.type); } // 处理触摸事件 void HandleTouchEvent(ArkUI_UIInputEvent *inputEvent) { auto pos = GetPointerPosition(inputEvent); auto baseInfo = GetBaseEventInfo(inputEvent); auto pointerCount = OH_ArkUI_PointerEvent_GetPointerCount(inputEvent); auto pointerId = OH_ArkUI_PointerEvent_GetPointerId(inputEvent, 0); auto pressure = OH_ArkUI_PointerEvent_GetPressure(inputEvent, 0); auto touchAreaWidth = OH_ArkUI_PointerEvent_GetTouchAreaWidth(inputEvent, 0); auto touchAreaHeight = OH_ArkUI_PointerEvent_GetTouchAreaHeight(inputEvent, 0); // 通过索引获取指针位置信息(支持多点触控场景) 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); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]", "[%{public}s] Touch: x=%{public}f, y=%{public}f, displayX=%{public}f, displayY=%{public}f, " "windowX=%{public}f, windowY=%{public}f, xByIndex=%{public}f, yByIndex=%{public}f, " "displayXByIndex=%{public}f, displayYByIndex=%{public}f, windowXByIndex=%{public}f, " "windowYByIndex=%{public}f, pointerCount=%{public}d, pointerId=%{public}d, " "pressure=%{public}f, touchAreaWidth=%{public}f, touchAreaHeight=%{public}f, " "action=%{public}d, eventTime=%{public}lld, sourceType=%{public}d, type=%{public}d", eventName_.c_str(), pos.x, pos.y, pos.displayX, pos.displayY, pos.windowX, pos.windowY, xByIndex, yByIndex, displayXByIndex, displayYByIndex, windowXByIndex, windowYByIndex, pointerCount, pointerId, pressure, touchAreaWidth, touchAreaHeight, baseInfo.action, baseInfo.eventTime, baseInfo.sourceType, baseInfo.type); } // 处理鼠标事件 void HandleMouseEvent(ArkUI_UIInputEvent *inputEvent) { auto pos = GetPointerPosition(inputEvent); auto baseInfo = GetBaseEventInfo(inputEvent); auto button = OH_ArkUI_MouseEvent_GetMouseButton(inputEvent); auto mouseAction = OH_ArkUI_MouseEvent_GetMouseAction(inputEvent); auto rawDeltaX = OH_ArkUI_MouseEvent_GetRawDeltaX(inputEvent); auto rawDeltaY = OH_ArkUI_MouseEvent_GetRawDeltaY(inputEvent); auto buttonCount = GetPressedButtonsCount(inputEvent); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]", "[%{public}s] Mouse: x=%{public}f, y=%{public}f, displayX=%{public}f, displayY=%{public}f, " "windowX=%{public}f, windowY=%{public}f, button=%{public}d, mouseAction=%{public}d, " "pressedButtonsCount=%{public}d, rawDeltaX=%{public}f, rawDeltaY=%{public}f, " "action=%{public}d, eventTime=%{public}lld, sourceType=%{public}d, type=%{public}d", eventName_.c_str(), pos.x, pos.y, pos.displayX, pos.displayY, pos.windowX, pos.windowY, button, mouseAction, buttonCount, rawDeltaX, rawDeltaY, baseInfo.action, baseInfo.eventTime, baseInfo.sourceType, baseInfo.type); } // 获取按下的鼠标按键数量 int32_t GetPressedButtonsCount(ArkUI_UIInputEvent *inputEvent) { int32_t pressedButtons[5] = {}; int32_t length = 5; OH_ArkUI_MouseEvent_GetPressedButtons(inputEvent, pressedButtons, &length); return length; } // 处理悬浮事件 void HandleHoverEvent(ArkUI_UIInputEvent *inputEvent) { auto pos = GetPointerPosition(inputEvent); auto baseInfo = GetBaseEventInfo(inputEvent); auto isHovered = OH_ArkUI_HoverEvent_IsHovered(inputEvent); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]", "[%{public}s] Hover: x=%{public}f, y=%{public}f, displayX=%{public}f, displayY=%{public}f, " "windowX=%{public}f, windowY=%{public}f, isHovered=%{public}d, action=%{public}d, " "eventTime=%{public}lld, sourceType=%{public}d, type=%{public}d", eventName_.c_str(), pos.x, pos.y, pos.displayX, pos.displayY, pos.windowX, pos.windowY, isHovered, baseInfo.action, baseInfo.eventTime, baseInfo.sourceType, baseInfo.type); } // 处理轴事件 void HandleAxisEvent(ArkUI_UIInputEvent *inputEvent) { auto baseInfo = GetBaseEventInfo(inputEvent); auto axisAction = OH_ArkUI_AxisEvent_GetAxisAction(inputEvent); auto verticalAxis = OH_ArkUI_AxisEvent_GetVerticalAxisValue(inputEvent); auto horizontalAxis = OH_ArkUI_AxisEvent_GetHorizontalAxisValue(inputEvent); auto pinchAxisScale = OH_ArkUI_AxisEvent_GetPinchAxisScaleValue(inputEvent); auto scrollStep = OH_ArkUI_AxisEvent_GetScrollStep(inputEvent); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]", "[%{public}s] Axis: axisAction=%{public}d, verticalAxis=%{public}f, horizontalAxis=%{public}f, " "pinchAxisScale=%{public}f, scrollStep=%{public}d, action=%{public}d, " "eventTime=%{public}lld, sourceType=%{public}d, type=%{public}d", eventName_.c_str(), axisAction, verticalAxis, horizontalAxis, pinchAxisScale, scrollStep, baseInfo.action, baseInfo.eventTime, baseInfo.sourceType, baseInfo.type); } // 处理按键事件 void HandleKeyEvent(ArkUI_UIInputEvent *inputEvent) { auto type = OH_ArkUI_KeyEvent_GetType(inputEvent); auto baseInfo = GetBaseEventInfo(inputEvent); auto deviceId = OH_ArkUI_UIInputEvent_GetDeviceId(inputEvent); auto keyInfo = GetKeyInfo(inputEvent); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]", "[%{public}s] Key: type=%{public}d, action=%{public}d, pressedKey=%{public}d, " "modifierKeys=%{public}llu, deviceId=%{public}d, eventTime=%{public}lld, sourceType=%{public}d", eventName_.c_str(), type, baseInfo.action, keyInfo.pressedKey, keyInfo.modifierKeys, deviceId, baseInfo.eventTime, baseInfo.sourceType); } // 获取按键信息 KeyInfo GetKeyInfo(ArkUI_UIInputEvent *inputEvent) { KeyInfo info; int32_t pressedKeys[10] = {}; int32_t length = 10; OH_ArkUI_UIInputEvent_GetPressedKeys(inputEvent, pressedKeys, &length); info.pressedKey = length > 0 ? pressedKeys[0] : -1; uint64_t modifierKeys = 0; OH_ArkUI_UIInputEvent_GetModifierKeyStates(inputEvent, &modifierKeys); info.modifierKeys = modifierKeys; return info; } std::string eventName_; EventType eventType_; }; // 创建列表项 std::shared_ptr<InputEventListItem> CreateEventListItem( const std::string& name, uint32_t color, InputEventListItem::EventType type) { return std::make_shared<InputEventListItem>(name, color, type); } // 创建按键事件按钮 ArkUI_NodeHandle CreateKeyEventButton(const char* name, uint32_t bgColor) { auto* nodeAPI = NativeModule::NativeModuleInstance::GetInstance()->GetNativeNodeAPI(); ArkUI_NodeHandle buttonHandle = nodeAPI->createNode(ARKUI_NODE_BUTTON); // 设置按钮属性 ArkUI_AttributeItem idItem = {.string = "keyEventButton"}; nodeAPI->setAttribute(buttonHandle, NODE_ID, &idItem); ArkUI_NumberValue typeValue[] = {{.i32 = 0}}; ArkUI_AttributeItem typeItem = {typeValue, 1}; nodeAPI->setAttribute(buttonHandle, NODE_BUTTON_TYPE, &typeItem); ArkUI_NumberValue widthValue[] = {{.f32 = 1.0f}}; ArkUI_AttributeItem widthItem = {widthValue, 1}; nodeAPI->setAttribute(buttonHandle, NODE_WIDTH_PERCENT, &widthItem); ArkUI_NumberValue heightValue[] = {{.f32 = 100.0f}}; ArkUI_AttributeItem heightItem = {heightValue, 1}; nodeAPI->setAttribute(buttonHandle, NODE_HEIGHT, &heightItem); ArkUI_NumberValue bgValue[] = {{.u32 = bgColor}}; ArkUI_AttributeItem bgItem = {bgValue, 1}; nodeAPI->setAttribute(buttonHandle, NODE_BACKGROUND_COLOR, &bgItem); ArkUI_AttributeItem labelItem = {.string = name}; nodeAPI->setAttribute(buttonHandle, NODE_BUTTON_LABEL, &labelItem); ArkUI_NumberValue focusable[] = {{.i32 = 1}}; ArkUI_AttributeItem focusableItem = {focusable, 1}; nodeAPI->setAttribute(buttonHandle, NODE_FOCUSABLE, &focusableItem); // 注册事件 nodeAPI->registerNodeEvent(buttonHandle, NODE_ON_CLICK_EVENT, 0, buttonHandle); nodeAPI->registerNodeEvent(buttonHandle, NODE_ON_KEY_EVENT, 0, buttonHandle); return buttonHandle; } // 处理按键按钮的点击事件 void HandleKeyEventButtonClick(ArkUI_NodeEvent *event) { ArkUI_NumberValue requestFocus[] = {{.i32 = 1}}; ArkUI_AttributeItem requestFocusItem = {requestFocus, 1}; auto* nativeModule = NativeModule::NativeModuleInstance::GetInstance()->GetNativeNodeAPI(); nativeModule->setAttribute( OH_ArkUI_NodeEvent_GetNodeHandle(event), NODE_FOCUS_STATUS, &requestFocusItem); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]", "[Key Event Button] Focus requested via click"); } // 处理按键按钮的按键事件 void HandleKeyEventButtonKey(ArkUI_NodeEvent *event) { auto *inputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event); auto type = OH_ArkUI_KeyEvent_GetType(inputEvent); auto action = OH_ArkUI_UIInputEvent_GetAction(inputEvent); auto deviceId = OH_ArkUI_UIInputEvent_GetDeviceId(inputEvent); int32_t pressedKeys[10] = {}; int32_t length = 10; OH_ArkUI_UIInputEvent_GetPressedKeys(inputEvent, pressedKeys, &length); auto pressedKey = length > 0 ? pressedKeys[0] : -1; uint64_t modifierKeys = 0; OH_ArkUI_UIInputEvent_GetModifierKeyStates(inputEvent, &modifierKeys); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[NdkBindInputEvent]", "[Key Event Button] Key: type=%{public}d, action=%{public}d, pressedKey=%{public}d, " "modifierKeys=%{public}llu, deviceId=%{public}d", type, action, pressedKey, modifierKeys, deviceId); } // 注册按键按钮的事件接收器 void RegisterKeyEventButtonReceiver(ArkUI_NodeHandle buttonHandle) { auto* nodeAPI = NativeModule::NativeModuleInstance::GetInstance()->GetNativeNodeAPI(); nodeAPI->addNodeEventReceiver(buttonHandle, [](ArkUI_NodeEvent *event) { auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); auto uiType = OH_ArkUI_UIInputEvent_GetType(OH_ArkUI_NodeEvent_GetInputEvent(event)); if (eventType == NODE_ON_CLICK_EVENT) { HandleKeyEventButtonClick(event); } else if (eventType == NODE_ON_KEY_EVENT && uiType == ARKUI_UIINPUTEVENT_TYPE_KEY) { HandleKeyEventButtonKey(event); } }); } // 添加所有事件列表项到列表 void AddEventListItems(std::shared_ptr<ArkUIListNode> list) { auto* nodeAPI = NativeModule::NativeModuleInstance::GetInstance()->GetNativeNodeAPI(); // 点击事件 list->AddChild(CreateEventListItem("Click Event - Tap to test", 0xFF1976D2, InputEventListItem::CLICK_EVENT)); // 触摸事件 list->AddChild(CreateEventListItem("Touch Event - Touch to test", 0xFF9E9E9E, InputEventListItem::TOUCH_EVENT)); // 鼠标事件 list->AddChild(CreateEventListItem("Mouse Event - Mouse over/click to test", 0xFF1976D2, InputEventListItem::MOUSE_EVENT)); // 悬浮事件 list->AddChild(CreateEventListItem("Hover Event - Hover to test", 0xFF9E9E9E, InputEventListItem::HOVER_EVENT)); // 轴事件 list->AddChild(CreateEventListItem("Axis Event - Use mouse wheel", 0xFF1976D2, InputEventListItem::AXIS_EVENT)); // 按键事件 ArkUI_NodeHandle keyButton = CreateKeyEventButton("Key Event - Click to focus, then press keys", 0xFF9E9E9E); RegisterKeyEventButtonReceiver(keyButton); nodeAPI->addChild(list->GetHandle(), keyButton); } // 创建输入事件列表的主函数 std::shared_ptr<ArkUIBaseNode> CreateTextListExample() { auto list = std::make_shared<ArkUIListNode>(); list->SetPercentWidth(1); list->SetPercentHeight(1); list->SetScrollBarState(true); // 添加所有事件列表项 AddEventListItems(list); return list; } } // namespace NativeModule #endif // MYAPPLICATION_NORMALTEXTLISTEXAMPLE_H由于使用了日志打印接口OH_LOG_Print,需要在CMakeLists.txt中添加对libhilog_ndk.z.so的引用。
add_library(entry SHARED napi_init.cpp NativeEntry.cpp) target_link_libraries(entry PUBLIC libace_napi.z.so libace_ndk.z.so libhilog_ndk.z.so)