harmony 鸿蒙自定义绘制

  • 2025-06-16
  • 浏览 (1)

自定义绘制

自定义绘制内容

当监听到注册的事件为绘制类型时,可通过自定义绘制功能执行绘制逻辑,自定义绘制的内容。 > 说明: > - 在事件注册过程中,需将事件注册为绘制事件(如ARKUI_NODE_CUSTOM_EVENT_ON_DRAW),通过查阅ArkUI_NodeCustomEventType枚举值,获取事件类型及含义。 > > - 若需实现自定义绘制逻辑,应自定义UserData,并在事件注册时进行传递。

  • 自定义节点的创建,通过ArkUI_NativeNodeAPI_1的create接口,传入ARKUI_NODE_CUSTOM创建自定义节点。

    auto customNode = nodeAPI->createNode(ARKUI_NODE_CUSTOM);
    
  • 在事件注册时将自定义节点、事件类型(例如ARKUI_NODE_CUSTOM_EVENT_ON_FOREGROUND_DRAW,获取NDK接口支持的事件类型范围可通过查询ArkUI_NodeCustomEventType枚举值)、事件ID和UserData作为参数传入。

    //UserData
    struct A {
        int32_t a =6;
        bool flag = true;
        ArkUI_NodeHandle node;
    };
    A *a = new A;
    a->node = customNode;
    nodeAPI->registerNodeCustomEvent(customNode,ARKUI_NODE_CUSTOM_EVENT_ON_FOREGROUND_DRAW,1,a);
    nodeAPI->registerNodeCustomEventReceiver([](ArkUI_NodeCustomEvent *event) {
    //事件回调函数逻辑
    });
    
  • 在回调函数中,获取自定义事件的事件类型(通过OH_ArkUI_NodeCustomEvent_GetEventType)、事件ID(通过OH_ArkUI_NodeCustomEvent_GetEventTargetId获取)、UserData(通过OH_ArkUI_NodeCustomEvent_GetUserData获取)进行判断,以执行不同的逻辑。

    auto type = OH_ArkUI_NodeCustomEvent_GetEventType(event);
    auto targetId = OH_ArkUI_NodeCustomEvent_GetEventTargetId(event);
    auto userData =reinterpret_cast<A *>( OH_ArkUI_NodeCustomEvent_GetUserData(event));
    
  • OH_ArkUI_NodeCustomEvent_GetDrawContextInDraw通过自定义组件事件获取绘制上下文,并将其传入 OH_ArkUI_DrawContext_GetCanvas中以获取绘制canvas指针,该指针随后转换为OH_Drawing_Canvas指针进行绘制。

    //获取自定义事件绘制的上下文。
    auto *drawContext = OH_ArkUI_NodeCustomEvent_GetDrawContextInDraw(event);
    //获取绘制canvas指针。
    auto *canvas1 = OH_ArkUI_DrawContext_GetCanvas(drawContext);
    //转换为OH_Drawing_Canvas指针进行绘制。
    OH_Drawing_Canvas *canvas = reinterpret_cast<OH_Drawing_Canvas *>(canvas1);
    //绘制逻辑。
    int32_t width = 1000;
    int32_t height = 1000;
    auto path = OH_Drawing_PathCreate();
    OH_Drawing_PathMoveTo(path, width / 4, height / 4);
    OH_Drawing_PathLineTo(path, width * 3 / 4, height * 3 / 4);
    OH_Drawing_PathLineTo(path, width * 3 / 4, height * 3 / 4);
    OH_Drawing_PathLineTo(path, width * 3 / 4, height * 3 / 4);
    OH_Drawing_PathLineTo(path, width * 3 / 4, height * 3 / 4);
    OH_Drawing_PathClose(path);
    auto pen = OH_Drawing_PenCreate();
    OH_Drawing_PenSetWidth(pen, 10);
    OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
    OH_Drawing_CanvasAttachPen(canvas, pen);
    OH_Drawing_CanvasDrawPath(canvas, path);
    

    完整示例:

ArkUI_NodeHandle test(ArkUI_NativeNodeAPI_1 *nodeAPI) {
    //创建节点
    auto column = nodeAPI->createNode(ARKUI_NODE_COLUMN);
    auto customNode = nodeAPI->createNode(ARKUI_NODE_CUSTOM);
    ArkUI_NumberValue value[] = {480};
    ArkUI_AttributeItem item = {value, 1};
    //属性设置
    nodeAPI->setAttribute(column, NODE_WIDTH, &item);
    value[0].i32 = 720;
    nodeAPI->setAttribute(column, NODE_HEIGHT, &item);
    ArkUI_NumberValue NODE_WIDTH_value[] = {200};
    ArkUI_AttributeItem NODE_WIDTH_Item[] = {NODE_WIDTH_value, 1};
    ArkUI_NumberValue NODE_HEIGHT_value[] = {200};
    ArkUI_AttributeItem NODE_HEIGHT_Item[] = {NODE_HEIGHT_value, 1};
    ArkUI_NumberValue NODE_BACKGROUND_COLOR_item_value[] = {{.u32 = 0xFFFFFF00}};
    ArkUI_AttributeItem NODE_BACKGROUND_COLOR_Item[] = {NODE_BACKGROUND_COLOR_item_value, 1};
    //自定义UserData。
    struct A {
        int32_t a =6;
        bool flag = true;
        ArkUI_NodeHandle node;
    };
    A *a = new A;
    a->node = customNode;
    nodeAPI->setAttribute(customNode, NODE_WIDTH, NODE_WIDTH_Item);
    nodeAPI->setAttribute(customNode, NODE_HEIGHT, NODE_HEIGHT_Item);
    nodeAPI->setAttribute(customNode, NODE_BACKGROUND_COLOR, NODE_BACKGROUND_COLOR_Item);
    //进行事件注册
    nodeAPI->registerNodeCustomEvent(customNode,ARKUI_NODE_CUSTOM_EVENT_ON_FOREGROUND_DRAW,1,a);
    //事件回调函数的编写
    nodeAPI->registerNodeCustomEventReceiver([](ArkUI_NodeCustomEvent *event) {
        //获取自定义事件的相关信息。
        auto type = OH_ArkUI_NodeCustomEvent_GetEventType(event);
        auto targetId = OH_ArkUI_NodeCustomEvent_GetEventTargetId(event);
        auto userData =reinterpret_cast<A *>( OH_ArkUI_NodeCustomEvent_GetUserData(event));
        if (type == ARKUI_NODE_CUSTOM_EVENT_ON_FOREGROUND_DRAW && targetId == 1 && userData->flag) {
            //获取自定事件绘制的上下文。
            auto *drawContext = OH_ArkUI_NodeCustomEvent_GetDrawContextInDraw(event);
            //获取绘制canvas指针。
            auto *canvas1 = OH_ArkUI_DrawContext_GetCanvas(drawContext);
            //转换为OH_Drawing_Canvas指针进行绘制。
            OH_Drawing_Canvas *canvas = reinterpret_cast<OH_Drawing_Canvas *>(canvas1);
            int32_t width = 1000;
            int32_t height = 1000;
            auto path = OH_Drawing_PathCreate();
            OH_Drawing_PathMoveTo(path, width / 4, height / 4);
            OH_Drawing_PathLineTo(path, width * 3 / 4, height * 3 / 4);
            OH_Drawing_PathLineTo(path, width * 3 / 4, height * 3 / 4);
            OH_Drawing_PathLineTo(path, width * 3 / 4, height * 3 / 4);
            OH_Drawing_PathLineTo(path, width * 3 / 4, height * 3 / 4);
            OH_Drawing_PathClose(path);
            auto pen = OH_Drawing_PenCreate();
            OH_Drawing_PenSetWidth(pen, 10);
            OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
            OH_Drawing_CanvasAttachPen(canvas, pen);
            OH_Drawing_CanvasDrawPath(canvas, path);
        }
    });
    //自定义节点上树
    nodeAPI->addChild(column, customNode);
    return column;
    }

自定义绘制

自定义绘制前景背景

以下示例创建了一个自定义绘制组件,该绘制组件能够绘制自定义矩形,同时可以自定义绘制前景和背景,并使用自定义布局容器进行布局排布。

  1. 按照自定义布局容器章节准备前置工程。

  2. 创建自定义绘制组件封装对象。 “`c // ArkUICustomNode.h // 自定义绘制组件示例

#ifndef MYAPPLICATION_ARKUICUSTOMNODE_H #define MYAPPLICATION_ARKUICUSTOMNODE_H

#include #include #include

#include “ArkUINode.h”

namespace NativeModule {

class ArkUICustomNode : public ArkUINode { public: // 使用自定义组件类型ARKUI_NODE_CUSTOM创建组件。 ArkUICustomNode() : ArkUINode((NativeModuleInstance::GetInstance()->GetNativeNodeAPI())->createNode(ARKUI_NODECUSTOM)) { // 注册自定义事件监听器。 nativeModule->addNodeCustomEventReceiver(handle, OnStaticCustomEvent); // 声明自定义事件并转递自身作为自定义数据。 nativeModule->registerNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_DRAWFRONT, 0, this);
nativeModule
->registerNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ONDRAW, 0, this); nativeModule->registerNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_BEHIND , 0, this);

}

~ArkUICustomNode() override {
    // 反注册自定义事件监听器。
    nativeModule_->removeNodeCustomEventReceiver(handle_, OnStaticCustomEvent);
    // 取消声明自定义事件。
    nativeModule_->unregisterNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_FRONT);        
    nativeModule_->unregisterNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW);
    nativeModule_->unregisterNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_BEHIND);
}

private: static void OnStaticCustomEvent(ArkUI_NodeCustomEvent *event) { // 获取组件实例对象,调用相关实例方法。 auto customNode = reinterpret_cast(OH_ArkUI_NodeCustomEvent_GetUserData(event)); auto type = OH_ArkUI_NodeCustomEvent_GetEventType(event); switch (type) { case ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_BEHIND: customNode->OnDrawBehind(event); break; case ARKUI_NODE_CUSTOM_EVENT_ON_DRAW: customNode->OnDraw(event); break; case ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_FRONT: customNode->OnDrawFront(event); break;
default: break; } }

// 自定义绘制逻辑。
void OnDrawBehind(ArkUI_NodeCustomEvent *event) {
    auto drawContext = OH_ArkUI_NodeCustomEvent_GetDrawContextInDraw(event);
    // 获取图形绘制对象。
    auto drawCanvas = reinterpret_cast<OH_Drawing_Canvas *>(OH_ArkUI_DrawContext_GetCanvas(drawContext));
    // 获取组件大小。
    auto size = OH_ArkUI_DrawContext_GetSize(drawContext);
    // 绘制自定义内容。
    auto path = OH_Drawing_PathCreate();
    OH_Drawing_PathMoveTo(path, size.width / 5, size.height / 5);
    OH_Drawing_PathLineTo(path, size.width * 4 / 5, size.height / 5);
    OH_Drawing_PathLineTo(path, size.width * 4 / 5, size.height * 4 / 5);
    OH_Drawing_PathLineTo(path, size.width / 5, size.height * 4 / 5);
    OH_Drawing_PathLineTo(path, size.width / 5, size.height / 5);
    OH_Drawing_PathClose(path);
    auto brush = OH_Drawing_BrushCreate();
    OH_Drawing_BrushSetColor(brush, 0xFFF0FAFF);// 蓝白色
    OH_Drawing_CanvasAttachBrush(drawCanvas, brush);
    OH_Drawing_CanvasDrawPath(drawCanvas, path);
    // 释放资源
    OH_Drawing_BrushDestroy(brush);
    OH_Drawing_PathDestroy(path);
}

void OnDraw(ArkUI_NodeCustomEvent *event) {
    auto drawContext = OH_ArkUI_NodeCustomEvent_GetDrawContextInDraw(event);
    // 获取图形绘制对象。
    auto drawCanvas = reinterpret_cast<OH_Drawing_Canvas *>(OH_ArkUI_DrawContext_GetCanvas(drawContext));
    // 获取组件大小。
    auto size = OH_ArkUI_DrawContext_GetSize(drawContext);
    // 绘制自定义内容。
    auto path = OH_Drawing_PathCreate();
    OH_Drawing_PathMoveTo(path, size.width / 4, size.height / 4);
    OH_Drawing_PathLineTo(path, size.width * 3 / 4, size.height / 4);
    OH_Drawing_PathLineTo(path, size.width * 3 / 4, size.height * 3 / 4);
    OH_Drawing_PathLineTo(path, size.width / 4, size.height * 3 / 4);
    OH_Drawing_PathLineTo(path, size.width / 4, size.height / 4);
    OH_Drawing_PathClose(path);
    auto brush = OH_Drawing_BrushCreate();
    OH_Drawing_BrushSetColor(brush, 0xff2787D9);// 浅蓝色
    OH_Drawing_CanvasAttachBrush(drawCanvas, brush);
    OH_Drawing_CanvasDrawPath(drawCanvas, path);
    // 释放资源
    OH_Drawing_BrushDestroy(brush);
    OH_Drawing_PathDestroy(path);
}

void OnDrawFront(ArkUI_NodeCustomEvent *event) {
    auto drawContext = OH_ArkUI_NodeCustomEvent_GetDrawContextInDraw(event);
    // 获取图形绘制对象。
    auto drawCanvas = reinterpret_cast<OH_Drawing_Canvas *>(OH_ArkUI_DrawContext_GetCanvas(drawContext));
    // 获取组件大小。
    auto size = OH_ArkUI_DrawContext_GetSize(drawContext);
    // 绘制自定义内容。
    auto path = OH_Drawing_PathCreate();
    OH_Drawing_PathMoveTo(path, size.width / 3, size.height / 3);
    OH_Drawing_PathLineTo(path, size.width * 2 / 3, size.height / 3);
    OH_Drawing_PathLineTo(path, size.width * 2 / 3, size.height * 2 / 3);
    OH_Drawing_PathLineTo(path, size.width / 3, size.height * 2 / 3);
    OH_Drawing_PathLineTo(path, size.width / 3, size.height / 3);
    OH_Drawing_PathClose(path);
    auto brush = OH_Drawing_BrushCreate();
    OH_Drawing_BrushSetColor(brush, 0xFF004AAF);// 深蓝色
    OH_Drawing_CanvasAttachBrush(drawCanvas, brush);
    OH_Drawing_CanvasDrawPath(drawCanvas, path);
    // 释放资源
    OH_Drawing_BrushDestroy(brush);
    OH_Drawing_PathDestroy(path);
}

};

} // namespace NativeModule

#endif // MYAPPLICATION_ARKUICUSTOMNODE_H


3. 使用自定义绘制组件和自定义容器创建示例界面
```c
// 自定义NDK接口入口组件。

#include <arkui/native_node_napi.h>
#include <arkui/native_type.h>
#include <js_native_api.h>

#include "NativeEntry.h"
#include "ArkUICustomContainerNode.h"
#include "ArkUICustomNode.h"

// 全局环境变量声明
static napi_env g_env = nullptr;

namespace NativeModule {

napi_value CreateNativeRoot(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1] = {nullptr};

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 获取NodeContent
    ArkUI_NodeContentHandle contentHandle;
    OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentHandle);
    NativeEntry::GetInstance()->SetContentHandle(contentHandle);

    // 创建自定义容器和自定义绘制组件。
    auto node = std::make_shared<ArkUICustomContainerNode>();
    node->SetBackgroundColor(0xFFD5D5D5);// 浅灰色
    auto customNode = std::make_shared<ArkUICustomNode>();
    customNode->SetBackgroundColor(0xFF707070);// 深灰色
    customNode->SetWidth(150);
    customNode->SetHeight(150);
    node->AddChild(customNode);

    // 保持Native侧对象到管理类中,维护生命周期。
    NativeEntry::GetInstance()->SetRootNode(node);
    g_env = env;
    return nullptr;
}

napi_value DestroyNativeRoot(napi_env env, napi_callback_info info) {
    // 从管理类中释放Native侧对象。
    NativeEntry::GetInstance()->DisposeRootNode();
    return nullptr;
}

} // namespace NativeModule

customDrawLayer

你可能感兴趣的鸿蒙文章

harmony 鸿蒙ArkUI(方舟UI框架)

harmony 鸿蒙全屏启动原子化服务组件(FullScreenLaunchComponent)

harmony 鸿蒙弧形按钮 (ArcButton)

harmony 鸿蒙动画衔接

harmony 鸿蒙动画概述

harmony 鸿蒙帧动画(ohos.animator)

harmony 鸿蒙实现属性动画

harmony 鸿蒙属性动画概述

harmony 鸿蒙弹出框概述

harmony 鸿蒙模糊

0  赞