文本输入框监听
〇、前言
文本输入框,是APP页面中与用户进行交互,获取用户数据的重要途径,监听文本输入框的改变、选择 是实现页面动态响应的重要基础,那么,在使用C++代码的开发的 NDK UI 中,文本输入框关键事件的监听要如何实现呢?下面就进行演示。

一、文本输入框关键事件
以文本输入域为例,借助监听关键事件的触发,从而完成页面的动态响应,那么,就不能错过这三种关键事件:NODE_TEXT_AREA_ON_CHANGE、NODE_TEXT_AREA_ON_PASTE、NODE_TEXT_AREA_ON_TEXT_SELECTION_CHANGE 。
1、NODE_TEXT_AREA_ON_CHANGE
开启了该事件监听的文本输入域,会在输入内容发生变更时触发,借助该事件的捕获,可以实现页面的实时刷新,比如将输入值关联到页面的一个文本组件上。
2、NODE_TEXT_AREA_ON_PASTE
PASTE,顾名思义,是粘贴的意思,而该事件就是在用户于文本输入域中进行粘贴操作才会触发。
3、NODE_TEXT_AREA_ON_TEXT_SELECTION_CHANGE
这一事件,触发时机就是用户在文本输入域中选中了一些文字或者移动了光标,监听该事件可以用于实现类似候选词联想的功能。
三、代码实践
文本输入框或输入域的事件处理流程,就跟按钮的点击事件的处理流程类似,都是先开启事件的监听,然后注册一个实现了事件处理逻辑的回调函数。
cpp
#ifndef NATIVEPC_TEXTAREAEVENTEXAMPLE_H
#define NATIVEPC_TEXTAREAEVENTEXAMPLE_H
#include <sstream>
#include "ArkUIBaseNode.h"
#include "ArkUIColumnNode.h"
#include "ArkUITextAreaNode.h"
#include "ArkUITextNode.h"
namespace NativeModule {
std::shared_ptr<ArkUIBaseNode> CreateTextAreaEventExample() {
showUITextCallback("文本事件处理", "文本框输入改变");
auto column = std::make_shared<ArkUIColumnNode>();
column->SetPercentHeight(1.0);
column->SetPercentWidth(1.0);
column->SetItemAlign(ARKUI_HORIZONTAL_ALIGNMENT_CENTER);
column->SetJustifyContent(ARKUI_FLEX_ALIGNMENT_START);
auto text = std::make_shared<ArkUITextNode>();
text->SetWidth(300);
text->SetHeight(100);
column->AddChild(text);
auto selectionText = std::make_shared<ArkUITextNode>();
selectionText->SetWidth(300);
selectionText->SetHeight(100);
column->AddChild(selectionText);
auto textArea = std::make_shared<ArkUITextAreaNode>();
textArea->SetWidth(300);
textArea->SetBorderWidth(1);
auto textAreaId = textArea->GetNodeId();
auto nodeApi = NativeModuleInstance::GetInstance()->GetNativeNodeAPI();
nodeApi->registerNodeEvent(textArea->GetHandle(), NODE_TEXT_AREA_ON_CHANGE, textAreaId, text->GetHandle());
nodeApi->registerNodeEvent(textArea->GetHandle(), NODE_TEXT_AREA_ON_PASTE, textAreaId, text->GetHandle());
nodeApi->registerNodeEvent(textArea->GetHandle(), NODE_TEXT_AREA_ON_TEXT_SELECTION_CHANGE, textAreaId, selectionText->GetHandle());
auto eventReceiver = [](ArkUI_NodeEvent *event){
ArkUI_NodeEventType eventType = OH_ArkUI_NodeEvent_GetEventType(event);
ArkUI_AttributeItem content;
if (eventType == NODE_TEXT_AREA_ON_CHANGE || eventType == NODE_TEXT_AREA_ON_PASTE) {
ArkUI_StringAsyncEvent *stringEvent = OH_ArkUI_NodeEvent_GetStringAsyncEvent(event);
content = {.string = stringEvent->pStr };
} else if (eventType == NODE_TEXT_AREA_ON_TEXT_SELECTION_CHANGE) {
ArkUI_NodeComponentEvent *componentEvent = OH_ArkUI_NodeEvent_GetNodeComponentEvent(event);
std::stringstream selectContent;
selectContent << "start: " << componentEvent->data[0].i32 << " , end: " << componentEvent->data[1].i32;
content = {.string = selectContent.str().c_str() };
} else {
return;
}
ArkUI_NodeHandle textNode = reinterpret_cast<ArkUI_NodeHandle>(OH_ArkUI_NodeEvent_GetUserData(event));
if (textNode) {
auto nodeApi = NativeModuleInstance::GetInstance()->GetNativeNodeAPI();
nodeApi->setAttribute(textNode, NODE_TEXT_CONTENT, &content);
}
};
textArea->RegisterNodeEventReceiver(eventReceiver);
column->AddChild(textArea);
return column;
}
}
#endif
案例代码中使用的组件,大部分都是之前就封装好的,唯有文本输入域组件,是第一次登场的,而 ArkUITextAreaNode 类的定义代码也很简单:
cpp
#ifndef NATIVEPC_ARKUITEXTAREANODE_H
#define NATIVEPC_ARKUITEXTAREANODE_H
#include "ArkUINode.h"
namespace NativeModule {
class ArkUITextAreaNode : public ArkUINode {
public:
ArkUITextAreaNode() : ArkUINode(NativeModuleInstance::GetInstance()->GetNativeNodeAPI()->createNode(ARKUI_NODE_TEXT_AREA)){}
};
}
#endif
之所以专门定义了一个类,是方便后面进行专有属性的扩展。
四、总结
无论是用 C++ 代码实现 NDK UI,还是之前用 ArkTS 实现的声明式UI,都可以看到匿名函数的身影,特别是在事件自定义处理代码片段中,几乎所有的回调函数都是用它来封装的。
在C++语法中,capture](parameters) { body }就是声明匿名函数的标志,类似于 ArkTS 的 () => {}。
C++ 的匿名函数(Lambda 表达式)是在 C++11 标准(ISO/IEC 14882:2011)中正式引入的。这是 C++
语言发展历程中的里程碑更新,显著提升了代码的灵活性和表达力。
更多有关 C++ 匿名函数的知识点,这里就不过多展开,还请有意者自行搜索了解。