鸿蒙NEXT开发键盘工具类(ArkTs)

news2025/4/20 9:30:21
export declare type KeyboardCallBack = (show: boolean, height: number) => void;
import { AppUtil } from './AppUtil';
import { LogUtil } from './LogUtil';
import { ArrayUtil } from './ArrayUtil';

/**
 * 键盘工具类
 * @author 鸿蒙布道师
 * @since 2025/04/18
 */
export class KeyboardUtil {
  private static callBacks: KeyboardCallBack[] = []; // 缓存的监听回调
  private static keyboardCallBack: ((height: number) => void) | undefined; // 全局键盘监听回调

  /**
   * 拉起键盘
   * @param key 输入框类组件的key或id
   * @param uiContext 页面的UIContext(子窗口需传入,主窗口可省略)
   */
  static show(key: string, uiContext?: UIContext): void {
    (uiContext ?? AppUtil.getUIContext()).getFocusController().requestFocus(key);
  }

  /**
   * 关闭键盘
   * @param uiContext 页面的UIContext(子窗口需传入,主窗口可省略)
   */
  static hide(uiContext?: UIContext): void {
    (uiContext ?? AppUtil.getUIContext()).getFocusController().clearFocus();
  }

  /**
   * 订阅输入法软键盘显示或隐藏事件
   * @param callback 回调函数:
   *         - show: boolean,true表示键盘显示,false表示键盘隐藏;
   *         - height: number,键盘高度。
   */
  static onKeyboardListener(callback: KeyboardCallBack): void {
    if (ArrayUtil.contain(KeyboardUtil.callBacks, callback)) {
      LogUtil.error(`KeyboardUtil-onKeyboardListener: 监听事件已存在!`);
      return;
    }

    KeyboardUtil.callBacks.push(callback);

    if (!KeyboardUtil.keyboardCallBack) {
      KeyboardUtil.keyboardCallBack = (height: number) => {
        KeyboardUtil.callBacks.forEach(cb => cb?.(height > 0, height));
      };
      AppUtil.getMainWindow().on('keyboardHeightChange', KeyboardUtil.keyboardCallBack);
    }
  }

  /**
   * 取消订阅输入法软键盘显示或隐藏事件
   * @param callback 要移除的监听事件,若不传则移除所有监听事件
   */
  static removeKeyboardListener(callback?: KeyboardCallBack): void {
    if (callback) {
      ArrayUtil.remove(KeyboardUtil.callBacks, callback);
    } else {
      KeyboardUtil.callBacks = [];
    }

    if (KeyboardUtil.keyboardCallBack && KeyboardUtil.callBacks.length === 0) {
      AppUtil.getMainWindow().off('keyboardHeightChange', KeyboardUtil.keyboardCallBack);
      KeyboardUtil.keyboardCallBack = undefined;
    }
  }
}

代码如下:
export declare type KeyboardCallBack = (show: boolean, height: number) => void;
import { AppUtil } from './AppUtil';
import { LogUtil } from './LogUtil';
import { ArrayUtil } from './ArrayUtil';

/**
 * 键盘工具类
 * @author 鸿蒙布道师
 * @since 2025/04/18
 */
export class KeyboardUtil {
  private static callBacks: KeyboardCallBack[] = []; // 缓存的监听回调
  private static keyboardCallBack: ((height: number) => void) | undefined; // 全局键盘监听回调

  /**
   * 拉起键盘
   * @param key 输入框类组件的key或id
   * @param uiContext 页面的UIContext(子窗口需传入,主窗口可省略)
   */
  static show(key: string, uiContext?: UIContext): void {
    (uiContext ?? AppUtil.getUIContext()).getFocusController().requestFocus(key);
  }

  /**
   * 关闭键盘
   * @param uiContext 页面的UIContext(子窗口需传入,主窗口可省略)
   */
  static hide(uiContext?: UIContext): void {
    (uiContext ?? AppUtil.getUIContext()).getFocusController().clearFocus();
  }

  /**
   * 订阅输入法软键盘显示或隐藏事件
   * @param callback 回调函数:
   *         - show: boolean,true表示键盘显示,false表示键盘隐藏;
   *         - height: number,键盘高度。
   */
  static onKeyboardListener(callback: KeyboardCallBack): void {
    if (ArrayUtil.contain(KeyboardUtil.callBacks, callback)) {
      LogUtil.error(`KeyboardUtil-onKeyboardListener: 监听事件已存在!`);
      return;
    }

    KeyboardUtil.callBacks.push(callback);

    if (!KeyboardUtil.keyboardCallBack) {
      KeyboardUtil.keyboardCallBack = (height: number) => {
        KeyboardUtil.callBacks.forEach(cb => cb?.(height > 0, height));
      };
      AppUtil.getMainWindow().on('keyboardHeightChange', KeyboardUtil.keyboardCallBack);
    }
  }

  /**
   * 取消订阅输入法软键盘显示或隐藏事件
   * @param callback 要移除的监听事件,若不传则移除所有监听事件
   */
  static removeKeyboardListener(callback?: KeyboardCallBack): void {
    if (callback) {
      ArrayUtil.remove(KeyboardUtil.callBacks, callback);
    } else {
      KeyboardUtil.callBacks = [];
    }

    if (KeyboardUtil.keyboardCallBack && KeyboardUtil.callBacks.length === 0) {
      AppUtil.getMainWindow().off('keyboardHeightChange', KeyboardUtil.keyboardCallBack);
      KeyboardUtil.keyboardCallBack = undefined;
    }
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2338639.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动态规划算法的欢乐密码(一):斐波那契数模型

专栏:算法的魔法世界 个人主页:手握风云 目录 一、动态规划 二、例题讲解 2.1. 第 N 个泰波那契数 2.2. 三步问题 2.3. 使用最小花费爬楼梯 2.4. 解码方法 一、动态规划 动态规划是一种将复杂问题分解为更小的子问题,并利用子问题的解来…

Echarts柱状图斜线环纹(图形的贴花图案)

单独设置 <!--此示例下载自 https://echarts.apache.org/examples/zh/editor.html?cbar-stack&codePYBwLglsB2AEC8sDeAoWszGAG0iAXMmuhgE4QDmFApqYQOQCGAHhAM70A0x6L7ACsAjQwtQqhIkwATxDUGbABaMAJsADu9HrAC-xHd3TZqNaCvEHiFcuaKTjAMzAMAzAFIu28hUXPY9ABYPQxIAI2AwTABbV…

2025.04.19【Spider】| 蜘蛛图绘制技巧精解

Basic multi-group radar chart Start with a basic version, learn how to format your input dataset Radar chart with ggradar A Spider chart made using the ggradar package and a lot of customization.A work by Tuo Wang 文章目录 Basic multi-group radar chartRa…

【Linux】深入理解Linux文件系统:从C接口到内核设计哲学

文章目录 前言一、C语言中的文件接口1. 文件指针&#xff08;句柄&#xff09;FILE*以写方式打开文件&#xff0c;若文件不存在会新建一个文件W写入方式&#xff0c;在打开文件之前都会将文件内容全部清空追加写方式&#xff0c;其用法与写方法一致&#xff0c;不同在于a方法可…

基于尚硅谷FreeRTOS视频笔记——15—系统配制文件说明与数据规范

目录 配置函数 INCLUDE函数 config函数 数据类型 命名规范 函数与宏 配置函数 官网上可以查找 最核心的就是 config和INCLUDE INCLUDE函数 这些就是裁剪的函数 它们使用一个ifndef。如果定义了&#xff0c;就如果定义了这个宏定义&#xff0c;那么代码就生效。 通过ifn…

Linux网络编程 深入解析TFTP协议:基于UDP的文件传输实战

知识点1【TFTP的概述】 学习通信的基本&#xff1a;通信协议&#xff08;具体发送上面样的报文&#xff09;、通信流程&#xff08;按照什么步骤发送&#xff09; 1、TFTP的概述 tftp&#xff1a;简单文件传输协议&#xff0c;**基于UDP&#xff0c;**不进行用户有效性验证 …

c# MES生产进度看板,报警看板 热流道行业可用实时看生产进度

MES生产进度看板&#xff0c;报警看板 热流道行业可用实时看生产进度 背景 本软件是给宁波热流道行业客户开发的生产电子看板软件系统 功能 1.录入工艺流程图&#xff08;途程图&#xff09;由多个站别组成。可以手动设置每个工艺站点完成百分比。 2.可以看生成到哪个工…

初识Redis · C++客户端string

目录 前言&#xff1a; string的API使用 set get&#xff1a; expire: NX XX: mset,mget&#xff1a; getrange setrange: incr decr 前言&#xff1a; 在前文&#xff0c;我们已经学习了Redis的定制化客户端怎么来的&#xff0c;以及如何配置好Redis定制化客户端&…

华硕原厂系统枪神9/9p超竟版-WIN11原装开箱出厂系统安装

华硕原厂系统枪神9/9p超竟版-WIN11-24H2-专业工作站版本安装可带F12-ASUSRecovery恢复功能 适用机型&#xff1a; G635LX、G635LW、G835LX、G835LW、G615LW、G615LP、G615LM、G615LH G815LW、G815LP、G815LM、G815LH、G635LR、G835LR、G615LR、G815LR 远程恢复安装&#xff…

CF1016赛后总结

文章目录 前言T1:Ideal GeneratorT2&#xff1a;Expensive NumberT3:Simple RepetitionT4&#xff1a;Skibidi TableT5:Min Max MEXT6:Hackers and Neural NetworksT7:Shorten the Array 前言 由于最近在半期考试&#xff0c;更新稍微晚了一点&#xff0c;还望大家见谅 &#…

QT聊天项目DAY06

1.从git上同步项目 编译测试&#xff0c;编译通过 Post请求测试 测试成功 2. email is 打印有问题&#xff0c;检查 解析结果是存储在jsonResult中的&#xff0c;修改 3. 客户端实现Post验证码请求 3.1 同步Qt客户端项目 检查QT版本&#xff0c;由于我在公司用的还是QT5.12.9…

GNU,GDB,GCC,G++是什么?与其他编译器又有什么关系?

文章目录 前言1. GNU和他的工具1.1 gcc与g1.2 gdb 2.Windows的Mingw/MSVC3.LLVM的clang/clang4.Make/CMake 前言 在开始之前我们先放一段Hello World&#xff1a;hello.c #include <stdio.h>int main() {printf("Hello World");return 0; }然后就是一段老生常…

笔记整理五

STP生成树 stp生成树是用于解决二层环路问题的协议。 二层环路为有以下三种&#xff1a; 1.广播风暴 2.MAC地址的偏移&#xff08;每一次循环&#xff0c;都会导致交换机来回刷新MAC地址表记录&#xff09; 3.多帧复制 stp生成树&#xff1a;需要将原本的环型拓扑结构转换…

奥比中光tof相机开发学习笔记

针对奥比中光 tof相机&#xff0c;官方提供的资料如下ProcessOn Mindmap|思维导图 Orbbec SDK Python Wrapper基于Orbbec SDK进行设计封装&#xff0c;主要实现数据流接收&#xff0c;设备指令控制。下面就其开发适配进行如下总结&#xff1a; &#xff08;1&#xff09;系统配…

【面试向】点积与注意力机制,逐步编码理解自注意力机制

点积&#xff08;dot product&#xff09;两个向量点积的数学公式点积&#xff08;dot product&#xff09;与 Attention 注意力机制&#xff08;Attention&#xff09;注意力机制的核心思想注意力机制中的缩放点积自注意力机制中&#xff0c;谁注意谁&#xff1f; 逐步编码理解…

一个 CTO 的深度思考

今天和一些同事聊了一会&#xff0c;以下是我的观点 我的观点&#xff0c;成年人只能筛选&#xff0c;不能培养在组织中&#xff0c;应该永远向有结果的人看齐。不能当他站出来讲话的时候&#xff0c;大家还要讨论讨论&#xff0c;他虽然拿到结果了&#xff0c;但是他就是有一…

SQL通用语法和注释,SQL语句分类(DDL,DML,DQL,DCL)及案例

目录 SQL通用语法和注释 SQL语句分类&#xff08;DDL&#xff0c;DML&#xff0c;DQL&#xff0c;DCL&#xff0c;TPL&#xff0c;CCL&#xff09; DDL&#xff08;数据定义语言&#xff09; 数据库操作 查询&#xff08;SHOW、SELECT&#xff09; 创建&#xff08;CREAT…

AUTOSAR图解==>AUTOSAR_SWS_KeyManager

AUTOSAR KeyManager详细分析 AUTOSAR 4.4.0 版本密钥与证书管理模块技术分析 目录 1. 概述2. KeyManager架构 2.1 KeyManager在AUTOSAR架构中的位置2.2 架构说明 3. KeyManager模块结构 3.1 模块组件详解3.2 配置项说明 4. KeyManager证书验证流程 4.1 证书验证流程分析 5. Ke…

Jsp技术入门指南【七】JSP动作讲解

Jsp技术入门指南【七】JSP动作讲解 前言一、什么是JSP动作&#xff1f;二、核心JSP动作详解1. jsp:include&#xff1a;动态包含其他页面与<% include %>的区别 2. jsp:forward&#xff1a;请求转发到另一个页面3. jsp:param&#xff1a;为动作传递参数4. jsp:useBean&am…

10软件测试需求分析案例-查询学习信息

用户登录系统后&#xff0c;进入查询学生信息界面&#xff0c;输入查询字段值&#xff0c;点击查询按钮后&#xff0c;展示查询到的学生信息&#xff0c;可以重新输入字段值进行查询。 查询学生信息属于学生信息管理的子菜单&#xff0c;可以根据学号、姓名、性别查询。老师登录…