占位组件

使用NDK接口构建UI界面时,需要在ArkTS页面创建用于挂载NDK接口创建组件的占位组件。占位组件类型为ContentSlot,ContentSlot能够绑定一个NodeContent对象,该对象可通过Node-API传递到Native侧挂载显示Native组件。

  • NDK配置文件oh-package.json5如下。

    
      
    1. {
    2. "name": "libentry.so",
    3. "types": "./index.d.ts",
    4. "version": "",
    5. "description": "Please describe the basic information."
    6. }
  • 占位组件和其他ArkTS系统组件使用方法相同。详细代码请参考示例

    
      
    1. import { NodeContent } from '@kit.ArkUI';
    2. @Entry
    3. @Component
    4. struct Index {
    5. // 初始化NodeContent对象。
    6. private rootSlot = new NodeContent();
    7. @State @Watch('changeNativeFlag') showNative: boolean = false;
    8. changeNativeFlag(): void {
    9. if (this.showNative) {
    10. // 传递NodeContent对象用于Native创建组件的挂载显示
    11. nativeNode.createNativeRoot(this.rootSlot)
    12. } else {
    13. // 销毁NativeModule组件
    14. nativeNode.destroyNativeRoot()
    15. }
    16. }
    17. build() {
    18. Column() {
    19. Button(this.showNative ? "HideNativeUI" : "ShowNativeUI").onClick(() => {
    20. this.showNative = !this.showNative
    21. })
    22. Row() {
    23. // 将NodeContent和ContentSlot占位组件绑定。
    24. ContentSlot(this.rootSlot)
    25. }.layoutWeight(1)
    26. }
    27. .width('100%')
    28. .height('100%')
    29. }
    30. }
  • 占位组件可以通过相关接口在Native侧转化为挂载对象。

    
      
    1. ArkUI_NodeContentHandle contentHandle;
    2. OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentHandle);
  • 挂载对象提供了相关挂载和卸载组件接口。

    
      
    1. OH_ArkUI_NodeContent_AddNode(handle_, myNativeNode);
    2. OH_ArkUI_NodeContent_RemoveNode(handle_, myNativeNode);

NDK组件模块

NDK提供的UI组件能力如组件创建、树操作、属性设置、事件注册等是通过函数指针结构体(如ArkUI_NativeNodeAPI_1)进行暴露,该函数指针结构体可以通过模块查询接口获取。


  1. ArkUI_NativeNodeAPI_1* arkUINativeNodeApi = nullptr;
  2. OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, arkUINativeNodeApi);

在获取到函数指针结构体后,可以使用该结构体内的函数实现相关UI组件操作。

  • 组件创建和销毁。

    
      
    1. auto listNode = arkUINativeNodeApi->createNode(ARKUI_NODE_LIST);
    2. arkUINativeNodeApi->disposeNode(listNode);

    获取NDK接口支持的组件范围可以通过查询ArkUI_NodeType枚举值。

  • 组件树操作。

    
      
    1. auto parent = arkUINativeNodeApi->createNode(ARKUI_NODE_STACK);
    2. auto child = arkUINativeNodeApi->createNode(ARKUI_NODE_STACK);
    3. arkUINativeNodeApi->addChild(parent, child);
    4. arkUINativeNodeApi->removeChild(parent, child);
  • 属性设置。

    
      
    1. auto stack = arkUINativeNodeApi->createNode(ARKUI_NODE_STACK);
    2. ArkUI_NumberValue value[] = {{.f32 = 100}};
    3. ArkUI_AttributeItem item = {value, 1};
    4. arkUINativeNodeApi->setAttribute(stack, NODE_WIDTH, &item);
    5. ArkUI_NumberValue value[] = {{.u32 = 0xff112233}};
    6. ArkUI_AttributeItem item = {value, 1};
    7. arkUINativeNodeApi->setAttribute(stack, NODE_BACKGROUND_COLOR, &item);

    获取NDK接口支持的属性范围可以通过查询ArkUI_NodeAttributeType枚举值。

  • 事件注册。

    
      
    1. auto stack = arkUINativeNodeApi->createNode(ARKUI_NODE_STACK);
    2. arkUINativeNodeApi->addNodeEventReceiver(stack, [](ArkUI_NodeEvent* event){
    3. // process event
    4. });
    5. arkUINativeNodeApi->registerNodeEvent(stack, NODE_ON_CLICK, 0, nullptr);

    获取NDK接口支持的事件范围可以通过查询ArkUI_NodeEventType枚举值。

示例

下面的示例展示了如何使用ContentSlot挂载Native侧的文本列表。

图1 Native文本列表

  1. 在ArkTS页面上声明用于Native页面挂载的占位组件,并在页面创建时通知Native侧创建文本列表。

    
      
    1. import nativeNode from 'libentry.so';
    2. import { NodeContent } from '@kit.ArkUI';
    3. @Entry
    4. @Component
    5. struct Index {
    6. // 初始化NodeContent对象。
    7. private rootSlot = new NodeContent();
    8. @State @Watch('changeNativeFlag') showNative: boolean = false;
    9. changeNativeFlag(): void {
    10. if (this.showNative) {
    11. // 传递NodeContent对象用于Native创建组件的挂载显示
    12. nativeNode.createNativeRoot(this.rootSlot)
    13. } else {
    14. // 销毁NativeModule组件
    15. nativeNode.destroyNativeRoot()
    16. }
    17. }
    18. build() {
    19. Column() {
    20. Button(this.showNative ? "HideNativeUI" : "ShowNativeUI").onClick(() => {
    21. this.showNative = !this.showNative
    22. })
    23. Row() {
    24. // 将NodeContent和ContentSlot占位组件绑定。
    25. ContentSlot(this.rootSlot)
    26. }.layoutWeight(1)
    27. }
    28. .width('100%')
    29. .height('100%')
    30. }
    31. }
  2. 使用Native模板创建工程,并在Native侧提供Node-API的桥接方法,实现ArkTS侧的NativeNode模块接口。

    接口声明。

    
      
    1. // entry/src/main/cpp/types/libentry/Index.d.ts
    2. export const createNativeRoot: (content: Object) => void;
    3. export const destroyNativeRoot: () => void;

    Native实现。

    
      
    1. // entry/src/main/cpp/napi_init.cpp
    2. #include "napi/native_api.h"
    3. #include "NativeEntry.h"
    4. EXTERN_C_START
    5. static napi_value Init(napi_env env, napi_value exports) {
    6. // 绑定Native侧的创建组件和销毁组件。
    7. napi_property_descriptor desc[] = {
    8. {"createNativeRoot", nullptr, NativeModule::CreateNativeRoot, nullptr, nullptr, nullptr, napi_default, nullptr},
    9. {"destroyNativeRoot", nullptr, NativeModule::DestroyNativeRoot, nullptr, nullptr, nullptr, napi_default, nullptr}};
    10. napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    11. return exports;
    12. }
    13. EXTERN_C_END
    14. static napi_module demoModule = {
    15. .nm_version = 1,
    16. .nm_flags = 0,
    17. .nm_filename = nullptr,
    18. .nm_register_func = Init,
    19. .nm_modname = "entry",
    20. .nm_priv = ((void *)0),
    21. .reserved = {0},
    22. };
    23. extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐