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)