「Unity3D」使用C#获取Android虚拟键盘的高度
原理是:利用getWindowVisibleDisplayFrame方法,获取Android窗口可见区域的Rect,这个Rect剔除了状态栏与导航栏,并且在有虚拟键盘遮挡的时候,会剔除这个遮挡区域。
接着,Unity的safeArea也剔除了状态栏与导航栏,且不会剔除虚拟键盘遮挡——那么,safeArea.height - getWindowVisibleDisplayFrame.height,就是虚拟键盘的高度。
public static float GetKeyboardHeight()
{#if UNITY_ANDROID && !UNITY_EDITORusing var unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");using var activity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");using var window = activity.Call<AndroidJavaObject>("getWindow");using var decorView = window.Call<AndroidJavaObject>("getDecorView"); using var rect = new AndroidJavaObject("android.graphics.Rect");decorView.Call("getWindowVisibleDisplayFrame", rect);return Screen.safeArea.height - rect.Call<int>("height");#elsereturn TouchScreenKeyboard.area.height;#endif
}
在实际中的问题是,虚拟键盘有动画,getWindowVisibleDisplayFrame获取有延迟,所以需要不断调用GetKeyboardHeight(),大概20帧左右,才能获取虚拟键盘高度的变化——于是Android的Java对象,就会反复创建与释放。
一个解决方案是,使用协程,即只在高度变化时才返回(利用IEnumerator的Current,也可以用回调函数),如下:
/// <summary>
/// Waits until the keyboard height is different from the [oldHeight], and return the new height with [IEnumerator.Current].
/// By using Coroutine to reduce the call and dispose of Java objects.
/// </summary>
public static IEnumerator GetKeyboardHeight(float oldHeight)
{#if UNITY_ANDROID && !UNITY_EDITORusing var unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");using var activity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");using var window = activity.Call<AndroidJavaObject>("getWindow");using var decorView = window.Call<AndroidJavaObject>("getDecorView"); using var rect = new AndroidJavaObject("android.graphics.Rect");while (true){decorView.Call("getWindowVisibleDisplayFrame", rect);var keyboardHeight = Screen.safeArea.height - rect.Call<int>("height");if (oldHeight != keyboardHeight){yield return keyboardHeight;yield break;}yield return null;}#elseyield return TouchScreenKeyboard.area.height;#endif
}
再给出一个,可以响应虚拟键盘不同状态的版本, 而safeArea.height也可以放到循环检测外面。
/// <summary>
/// Waits until the keyboard height is different from the [oldHeight], and return the new height with [IEnumerator.Current].
/// If [IEnumerator.Current] is 0.0f, the keyboard needs to be closed.
/// By using Coroutine to reduce the call and dispose of Java objects.
/// </summary>
public static IEnumerator GetKeyboardHeight(float oldHeight, TouchScreenKeyboard keyboard)
{#if UNITY_ANDROID //&& !UNITY_EDITORusing var unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");using var activity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");using var window = activity.Call<AndroidJavaObject>("getWindow");using var decorView = window.Call<AndroidJavaObject>("getDecorView"); using var rect = new AndroidJavaObject("android.graphics.Rect");var safeAreaHeight = Screen.safeArea.height;while (true){switch (keyboard.status){case TouchScreenKeyboard.Status.Visible:decorView.Call("getWindowVisibleDisplayFrame", rect);var keyboardHeight = safeAreaHeight - rect.Call<int>("height");if (oldHeight != keyboardHeight){yield return keyboardHeight;yield break;} break;case TouchScreenKeyboard.Status.Done:case TouchScreenKeyboard.Status.Canceled:case TouchScreenKeyboard.Status.LostFocus:yield return 0.0f;yield break;}yield return null;}#elseyield return TouchScreenKeyboard.area.height;#endif
}
相关文章:
「Unity3D」使用C#获取Android虚拟键盘的高度
原理是:利用getWindowVisibleDisplayFrame方法,获取Android窗口可见区域的Rect,这个Rect剔除了状态栏与导航栏,并且在有虚拟键盘遮挡的时候,会剔除这个遮挡区域。 接着,Unity的safeArea也剔除了状态栏与导…...
近场通信(NFC)在电动车启动系统中的技术实现路径
电动车NFC一键启动系统基于13.56MHz频段实现非接触控制,技术方案要点如下: 系统架构 硬件核心 NFC芯片(如N32G45x)处理通信协议,支持手机/卡片识别STM32主控解析指令,AES-128加密模块保障双向认证…...
斜线、短横、空格,三种分隔日期的优雅解析(Python | DeepSeek)
标准日期解析操作,str.replace链式如灵蛇蜿蜒,三元表达式像空灵仙家妙法。 笔记模板由python脚本于2025-03-25 22:32:24创建,本篇笔记适合三元表达式、字符串操作修习的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值:在…...
自动化逆向框架使用(Objection+Radare2)
1. 工具链架构与核心优势 1.1 动静结合逆向体系 graph LR A[动态分析] -->|Objection实时Hook| B[关键点定位] B --> C[行为数据捕获] D[静态分析] -->|Radare2深度解析| E[控制流重建] E --> F[漏洞模式识别] B --> F C --> F 组合优势对比&…...
inline 配置全局参数变量
在 C 中,对于头文件中定义的全局变量,使用 inline 比 static 更优,主要原因如下: 1. 避免重复定义的多个副本 static 的问题 每个包含该头文件的 .cpp 都会生成一个独立的变量副本,导致: 内存浪费…...
(C语言)静态通讯录(正式版)(C语言小项目)
1.首先是头文件: //头文件 //contact.h//防止头文件被重复包含 #pragma once //定义符号常亮,方便维护和修改 //联系人基本信息容量 #define NAME_MAX 20 #define AGE_MAX 5 #define SEX_MAX 5 #define TELE_MAX 15 #define ADDR_MAX 30 //联系人最大容量…...
Windows 计划任务服务(Task Scheduler)
svchost.exe -k netsvcs -p -s Schedule 是 Windows 计划任务服务(Task Scheduler) 的标准启动命令,通常用于管理系统定时任务。以下是详细解析: 命令拆解 svchost.exe Windows 核心进程,用于托管系统服务(…...
[特殊字符] 2025蓝桥杯备赛Day13——P10984 [蓝桥杯 2023 国 Python A] 残缺的数字
🔍 2025蓝桥杯备赛Day13——P10984 [蓝桥杯 2023 国 Python A] 残缺的数字 🚀 题目速览 题目难度:⭐⭐⭐(需掌握位运算与组合数学) 考察重点:二进制状态处理、位运算、乘法原理、枚举 P10984 [蓝桥杯 2…...
线程控制与线程库
目录 解析tid 线程的地址空间布局 线程栈 我们来学习线程控制与线程库 解析tid #include<iostream> #include<string> #include<cstdio> #include<cstring> #include<unistd.h> #include<thread> using namespace std;int shared_val…...
P1182 数列分段 Section II
P1182 数列分段 Section II - 洛谷 题目描述 对于给定的一个长度为 N 的正整数数列 A1∼AN,现要将其分成 M(M≤N)段,并要求每段连续,且每段和的最大值最小。 关于最大值最小: 例如一数列 4 2 4 5 1…...
比手动备份快 Iperius全自动加密备份,NAS/云盘/磁带机全兼容
IperiusBackupFull是一款专为服务器和工作站设计的备份解决方案,它同时也是一款针对Windows 7/8/10/11/Server系统的简洁且可靠的备份软件。该软件支持增量备份、数据同步以及驱动器镜像,确保能够实现完全的系统恢复。在备份存储方面,Iperius…...
从概率到梯度:理解分类问题中交叉熵的优越性
分类问题一般使用交叉熵(Cross-Entropy)而不是平方损失(Square Loss)函数1. **概率解释**2. **梯度性质**3. **对错误的惩罚**4. **计算复杂度**5. **总结** 分类问题一般使用交叉熵(Cross-Entropy)而不是平…...
2025最新版Ubuntu Server版本Ubuntu 24.04.2 LTS下载与安装-详细教程,细致到每一步都有说明
官网 https://ubuntu.com/ 下载 点击菜单 Prodercts> Ubuntu OS>Ubuntu Server 点击下载 下载后会有个弹窗 安装 选择第一个 install Ubuntu Server 直接默认,选择English 【默认】 选择键盘布局【默认】 选择安装配置【默认】 配置网络 我这里选择…...
更新测试环境构建命令以解决构建失败问题
本段代码解决 更新测试环境构建命令以解决构建失败问题 //本项目是reactumi3antdesign 搭建的后台管理系统 "build:test": "cross-env UMI_ENVtest NODE_OPTIONS--openssl-legacy-provider umi build"**原因:**Node.js v17 的 OpenSSL 3.0 与旧…...
C 语言中, scanf 函数在哪些情况下会结束输入读取:
在 C 语言中, scanf 函数在以下几种情况下会结束输入读取: : 1. 遇到指定格式匹配失败: scanf 按照格式字符串要求读取输入。当输入数据格式与格式字符串不匹配时,就会结束读取。例如 scanf(“%d”, &num) 要求输…...
树莓派5-GPIO和40针引脚
1.树莓派5引脚图 2.GPIO 引脚作用 (1) 电压 板上有两个 5V 引脚和两个 3.3V 引脚,以及一些不可配置的接地引脚 (0V)。其余引脚均为通用 3.3V 引 脚,这意味着输出设置为 3.3V,输入可接 3.3V。 (2) 输出 指定为输出引脚的 GPIO 引脚可设置为…...
【数据库】sql错题详解
1. 执行子查询 SELECT 供应商号 FROM 订购单 WHERE 职工号 IN (E1, E3) GROUP BY 供应商号 HAVING COUNT(DISTINCT 职工号) 2筛选职工号为 E1 或 E3 的记录: 依据 WHERE 职工号 IN (E1, E3) 这个条件,从 订购单 表中把职工号为 E1 或者 E3 的记录筛选出…...
搭建主从DNS、nfs、nginx
任务需求: 客户端通过访问 www.nihao.com 后,能够通过 dns 域名解析,访问到 nginx 服务中由 nfs 共享的首页文件,内容为:Very good, you have successfully set up the system. 各个主机能够实现时间同步,…...
C#重写treeView控件
1.先准备两张图片downdrop.png、downdrop_open.png放在项目Resources里 2.新建用户控件BaseTreeView控件 3.重写控件继承TreeView,记得删除AutoScaleMode这一行,否则会报错 public partial class BaseTreeView : TreeView {//这个属性貌似不起作用&…...
JS自动装箱(Auto-boxing)机制深度解析
📦 JS自动装箱(Auto-boxing)机制深度解析 自动装箱(Autoboxing) 是 JavaScript 的一项特性 🌟 核心概念速览 自动装箱 原始值临时变身对象 当对原始值调用方法或访问属性时,JS 引擎会自动将其转换为对应的包装对象&…...
ArcGIS 10.8.1之后发布栅格数据的MapServer 动态工作空间 替换数据源渲染问题
背景 经过测试,Server 10.8.1、11.0、11.1发布相关服务设置动态空间之后,前端都无法自动读取同名的clr色彩映射表文件进行渲染,服务都是由ArcGIS Pro进行发布。 原因 基于ArcMap发布的服务才支持,但是10.8.1之后不支持ArcMap发…...
Java集合框架深度剖析:从数据结构到实战应用
引言 Java集合框架是Java开发中的核心组件之一,其设计目标是提供高性能、高复用性的数据容器。无论是数据处理、缓存设计还是高并发场景,集合框架都扮演着关键角色。本文将从List、Map、Set三大核心接口出发,深入剖析其主流实现类࿰…...
【MySQL】监控MySQL
目录 使用状态变量监控MySQL 使用性能模式(Performance Schema)监控MySQL 1.性能模式 2.性能模式设置表 3.sys模式 使用状态变量监控MySQL 使用 show status 语句评估系统运行状况。 可以添加范围修饰符global或session来显示全局或本地状态信息。…...
涅槃上岸,入陕进军,复试全程流程开启!
复试决胜局,整装待发,上岸西电! 线下复试注意事项、全流程、录取后西安旅游提前告知! 过两天考研复试笔试、机试(如果有)、面试就要开始了,我们需要准备很多东西,学长从以下几个方面…...
msyql--基本操作之运维篇
检查 root 用户的权限 查看该用户针对这个数据库的权限 -- 如果在终端连接mysql时需要 mysql -u root -p -- 查看用户权限 SELECT user, host FROM mysql.user WHERE user root;可以看的出来root有他的访问权限,如过没有localhost或者% 说明没有访问权限 添加…...
鸿蒙开发:openCustomDialog关闭指定Dialog
前言 本文基于Api13 openCustomDialog弥补了CustomDialogController在使用上存在的诸多限制,实现了可以在任意位置上弹出,可以说是非常的方便;但是,在使用的时候遇到了一些小阻碍,比如一个页面中可能存在多个弹窗&…...
es6 fetch
对比XHR 🛠️ fetch 所有配置项 fetch(url, {// 核心配置 method: GET, // HTTP 方法: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONSheaders: { // 请求头(支持 Headers 对象或普通对象)Content-Type: applicati…...
Apache Tomcat RCE漏洞(CVE-2025-24813)
一,漏洞描述 该漏洞在于 Tomcat 在处理不完整PUT请求上传时,会使用了一个基于用户提供的文件名和路径生成的临时文件。 二,漏洞条件 1,默认 Servlet 启用了写权限(默认禁用) 2,启用了部分PUT…...
Apache HttpClient使用
一、Apache HttpClient 基础版 HttpClients 是 Apache HttpClient 库中的一个工具类,用于创建和管理 HTTP 客户端实例。Apache HttpClient 是一个强大的 Java HTTP 客户端库,用于发送 HTTP 请求并处理 HTTP 响应。HttpClients 提供了多种方法来创建和配…...
智能汽车图像及视频处理方案,支持视频星轨拍摄能力
美摄科技作为智能汽车图像及视频处理领域的先行者,正以革新性的技术引领着行业的未来发展。美摄科技智能汽车图像及视频处理方案,一个集高效性、智能化、画质增强于一体的创新解决方案,旨在重塑智能汽车图像画质的新标准,并支持前…...
