HarmonyOS Next开发----使用XComponent自定义绘制

XComponent组件作为一种绘制组件,通常用于满足用户复杂的自定义绘制需求,其主要有两种类型"surface和component。对于surface类型可以将相关数据传入XComponent单独拥有的NativeWindow来渲染画面。

由于上层UI是采用arkTS开发,那么想要使用XComponent的话,就需要一个桥接和native层交互,类似Android的JNI,鸿蒙应用可以使用napi接口来处理js和native层的交互。

1. 编写CMAKELists.txt文件
# the minimum version of CMake.
cmake_minimum_required(VERSION 3.4.1)
project(XComponent) #项目名称

set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
#头文件查找路径
include_directories(
    ${NATIVERENDER_ROOT_PATH}
    ${NATIVERENDER_ROOT_PATH}/include
)
# 编译目标so动态库
add_library(nativerender SHARED
    samples/minute_view.cpp
    plugin/plugin_manager.cpp
    common/HuMarketMinuteData.cpp
    common/MinuteItem.cpp
    napi_init.cpp
)
# 查找需要的公共库
find_library(
    # Sets the name of the path variable.
    hilog-lib
    # Specifies the name of the NDK library that
    # you want CMake to locate.
    hilog_ndk.z
)
#编译so所需要的依赖
target_link_libraries(nativerender PUBLIC
    libc++.a
    ${hilog-lib}
    libace_napi.z.so
    libace_ndk.z.so
    libnative_window.so
    libnative_drawing.so
)
2. Napi模块注册
#include <hilog/log.h>
#include "plugin/plugin_manager.h"
#include "common/log_common.h"

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
   
   
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Init", "Init begins");
    if ((nullptr == env) || (nullptr == exports)) {
   
   
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Init", "env or exports is null");
        return nullptr;
    }

    PluginManager::GetInstance()->Export(env, exports);
    return exports;
}
EXTERN_C_END

static napi_module nativerenderModule = {
   
   
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "nativerender",
    .nm_priv = ((void *)0),
    .reserved = {
   
    0 }
};

extern "C" __attribute__((constructor)) void RegisterModule(void)
{
   
   
    napi_module_register(&nativerenderModule);
}

定义napi_module信息,里面包含模块名称(和arkts侧使用时的libraryname要保持一致),加载模块时的回调函数即Init()。然后注册so模块napi_module_register(&nativerenderModule), 接口Init()函数会收到回调,在Init()有两个参数:

  • env: napi上下文环境;
  • exports: 用于挂载native函数将其导出,会通过js引擎绑定到js层的一个js对象;
3.解析XComponent组件的NativeXComponent实例
 if ((env == nullptr) || (exports == nullptr)) {
   
   
        DRAWING_LOGE("Export: env or exports is null");
        return;
    }

    napi_value exportInstance = nullptr;
     // 用来解析出被wrap了NativeXComponent指针的属性
    if (napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
   
   
        DRAWING_LOGE("Export: napi_get_named_property fail");
        return;
    }

    OH_NativeXComponent *nativeXComponent = nullptr;
    // 通过napi_unwrap接口,解析出NativeXComponent的实例指针
    if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
   
   
        DRAWING_LOGE("Export: napi_unwrap fail");
        return;
    }

    char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {
   
   '\0'};
    uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
    if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
   
   
        DRAWING_LOGE("Export: OH_NativeXComponent_GetXComponentId fail");
        return;
    }
4.注册XComponent事件回调
void MinuteView::RegisterCallback(OH_NativeXComponent *nativeXComponent) {
   
   
    DRAWING_LOGI("register callback");
    renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
    renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
    renderCallback_.DispatchTouchEvent = nullptr;
    renderCallback_.OnSurfaceChanged = OnSurfaceChanged;
    // 注册XComponent事件回调
    OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);
}

在事件回调中可以获取组件的宽高信息:

tatic void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
   
   
    DRAWING_LOGI("OnSurfaceCreatedCB");
    if ((component == nullptr) || (window == nullptr)) {
   
   
        DRAWING_LOGE("OnSurfaceCreatedCB: component or window is null");
        return;
    }
    char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {
   
   '\0'};
    uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
    if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
   
   
        DRAWING_LOGE("OnSurfaceCreatedCB: Unable to get XComponent id");
        return
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值