1、场景介绍

对于存在Tab页的应用,如华为浏览器,窗口的拖拽分合是关键体验。

图8-1

2、功能介绍

2.1 隐藏系统标题栏

  • 系统标题栏无法实现Tab页签功能,首先通过setWindowDecorVisible()接口隐藏系统标题栏,应用实现自定义标题栏。
setWindowDecorVisible(isVisible: boolean): void

2.2 禁用系统标题栏默认移动窗口的能力

  • 隐藏系统标题栏后,标题栏变为透明,但是标题栏默认移动窗口的能力仍然存在;对于存在Tab页的应用,如华为浏览器,为了实现自定义Tab页签的拖动效果,需通过setWindowTitleMoveEnabled接口实现禁止/使能窗口标题栏默认移动窗口和双击最大化的功能。
setWindowTitleMoveEnabled(enabled: boolean): void

2.3 窗口分合场景下,实现输入事件转移

  • 窗口缝合场景下,仍然需要上述接口实现输入事件从源窗口转移至目标窗口。

2.4 使用startMoving()实现窗口拖动

在同应用内窗口分合后,且鼠标保持按下状态直接移动新窗口,如果此时鼠标快速移动,窗口移动时鼠标可能会在窗口外。可以使用startMoving(offsetX: number, offsetY: number)接口指定窗口移动时鼠标在窗口内的位置,先移动窗口到鼠标位置,再开始移动窗口。

2.5 通过NDK接口实现输入事件监听

开发者可以NativeWindowEventFilter模块提供的能力去监听和拦截输入事件,让输入事件不往应用内部组件分发。当使用startMoving()实现窗口拖动时,输入事件将被系统接管,应用无法通过应用内部组件监听输入事件,因此系统提供了以下NDK接口实现对输入事件的监听和拦截。

名称

typedef关键字

描述

typedef bool (*OH_NativeWindowManager_MouseEventFilter)(Input_MouseEvent* mouseEvent)

OH_NativeWindowManager_MouseEventFilter

定义多模鼠标事件的过滤函数。

WindowManager_ErrorCode OH_NativeWindowManager_RegisterMouseEventFilter(int32_t windowId,OH_NativeWindowManager_MouseEventFilter mouseEventFilter)

-

注册鼠标事件的过滤函数。

WindowManager_ErrorCode OH_NativeWindowManager_UnregisterMouseEventFilter(int32_t windowId)

-

取消注册窗口的鼠标事件过滤函数。

typedef bool (*OH_NativeWindowManager_TouchEventFilter)(Input_TouchEvent* touchEvent)

OH_NativeWindowManager_TouchEventFilter

定义多模触摸事件的过滤函数。

WindowManager_ErrorCode OH_NativeWindowManager_RegisterTouchEventFilter(int32_t windowId,OH_NativeWindowManager_TouchEventFilter touchEventFilter)

-

注册触摸事件的过滤函数。

WindowManager_ErrorCode OH_NativeWindowManager_UnregisterTouchEventFilter(int32_t windowId)

-

取消注册窗口的触摸事件过滤函数

2.6 使用stopMoving()实现终止窗口拖动

在窗口拖动过程中,应用可以通过stopMoving()终止窗口拖动,如在ESC按键回调中调用stopMoving(),即可实现ESC按键终止窗口拖动的功能。

3、适配指导

  • 使用NativeWindowEventFilter模块提供的能力去监听和拦截输入事件。
  • 在CMake脚本中链接动态库
target_link_libraries(entry PUBLIC libnative_window_manager.so libohinput.so) 
  • 添加头文件
#include "window_manager/oh_window_comm.h"
#include "window_manager/oh_window_event_filter.h"
#include "multimodalinput/oh_input_manager.h"
  • 接口使用说明
    • 应用窗口创建后,通过窗口ID去绑定窗口的鼠标事件/触摸事件过滤函数。
    • 应用窗口需要收到鼠标事件/触摸事件时,窗口才可触发鼠标事件/触摸事件的拦截。
    • 当回调函数返回值为true表示拦截,为false不拦截。
    • 同一个窗口ID注册的回调函数只允许一个,最后注册的回调函数会覆盖之前注册过的回调函数。
  • 示例代码
#include "napi/native_api.h"
#include "window_manager/oh_window_comm.h"
#include "window_manager/oh_window_event_filter.h"
#include "multimodalinput/oh_input_manager.h"
//设置鼠标事件过滤函数
static bool filterMouseEvent(Input_MouseEvent* mouseEvent) {
    int32_t action = OH_Input_GetMouseEventAction(mouseEvent);
    int32_t displayX = OH_Input_GetMouseEventDisplayX(mouseEvent);
    int32_t displayY = OH_Input_GetMouseEventDisplayY(mouseEvent);
    int32_t mouseButton = OH_Input_GetMouseEventButton(mouseEvent);
    int64_t actionTime = OH_Input_GetMouseEventActionTime(mouseEvent);
    // 过滤鼠标右键按下
     return (action == Input_MouseEventAction::MOUSE_ACTION_BUTTON_DOWN
        && mouseButton == Input_MouseEventButton::MOUSE_BUTTON_RIGHT);
}
//设置触摸事件过滤函数
static bool filterTouchEvent(Input_TouchEvent* touchEvent) {
    int32_t action = OH_Input_GetTouchEventAction(touchEvent);
    int32_t id = OH_Input_GetTouchEventFingerId(touchEvent);
    int32_t displayX = OH_Input_GetTouchEventDisplayX(touchEvent);
    int32_t displayY = OH_Input_GetTouchEventDisplayY(touchEvent);
    int64_t actionTime = OH_Input_GetTouchEventActionTime(touchEvent);
    //过滤触摸移动事件
    return action == Input_TouchEventAction::TOUCH_ACTION_MOVE;
}
static napi_value registerMouseFilter(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);
    int32_t windowId;
    napi_get_value_int32(env, args[0], &windowId);
    auto result = OH_NativeWindowManager_RegisterMouseEventFilter(windowId, filterMouseEvent);
    napi_value errCode;
    napi_create_int32(env, result, &errCode);
    return errCode;
}
static napi_value clearMouseFilter(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);

    int32_t windowId;
    napi_get_value_int32(env, args[0], &windowId);

    auto result = OH_NativeWindowManager_UnregisterMouseEventFilter(windowId);
    napi_value errCode;
    napi_create_int32(env, result, &errCode);
    return errCode;
}
static napi_value registerTouchFilter(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);
    int32_t windowId;
    napi_get_value_int32(env, args[0], &windowId);
    auto result = OH_NativeWindowManager_RegisterTouchEventFilter(windowId, filterTouchEvent);
    napi_value errCode;
    napi_create_int32(env, result, &errCode);
    return errCode;
}
static napi_value clearTouchFilter(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);

    int32_t windowId;
    napi_get_value_int32(env, args[0], &windowId);

    auto result = OH_NativeWindowManager_UnregisterTouchEventFilter(windowId);
    napi_value errCode;
    napi_create_int32(env, result, &errCode);
    return errCode;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
  napi_property_descriptor desc[] = {
    {"registerMouseFilter", nullptr, registerMouseFilter, nullptr, nullptr, nullptr, napi_default, nullptr},
    {"clearMouseFilter", nullptr, clearMouseFilter, nullptr, nullptr, nullptr, napi_default, nullptr},
    {"registerTouchFilter", nullptr, registerTouchFilter, nullptr, nullptr, nullptr, napi_default, nullptr},
    {"clearTouchFilter", nullptr, clearTouchFilter, nullptr, nullptr, nullptr, napi_default, nullptr},
  };
  napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
  return exports;
}
EXTERN_C_END
Logo

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

更多推荐