「Unity3D」使用C#获取Android虚拟键盘的高度

原理是:利用getWindowVisibleDisplayFrame方法,获取Android窗口可见区域的Rect,这个Rect剔除了状态栏与导航栏,并且在有虚拟键盘遮挡的时候,会剔除这个遮挡区域。

接着,UnitysafeArea也剔除了状态栏与导航栏,且不会剔除虚拟键盘遮挡——那么,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帧左右,才能获取虚拟键盘高度的变化——于是AndroidJava对象,就会反复创建与释放。

一个解决方案是,使用协程,即只在高度变化时才返回(利用IEnumeratorCurrent,也可以用回调函数),如下:

/// <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
}

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

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

相关文章

“城市超级智能体”落地,联想智慧城市4.0“功到自然成”

作者 | 曾响铃 文 | 响铃说 交通摄像头捕捉到车流量数据&#xff0c;进入一套“自动化”的城市整体管理体系中&#xff0c;交通路况信息、天气变化情况以及城市大型活动安排等看似分散的数据被整合&#xff0c;根据预测的路况精准调控交通信号灯&#xff0c;让自动驾驶清扫车…

每日总结3.24

第十届蓝桥杯大赛软件赛省赛C/C 大学 B 组 183.完全二叉树的权值&#xff08;找规律&#xff0c;临界值&#xff09; #include <bits/stdc.h> using namespace std; int a[1000005]; int main() { int m;int d; cin>>m; int sum;int maxn0; for(int i1;i&…

计算机复试面试

数据库 1.设计过程/设计步骤 1.需求分析&#xff1a;明确客户需求&#xff0c;确定系统边界&#xff0c;生成数据字典 2.概念结构设计&#xff1a;将用户需求抽象为概念模型&#xff0c;绘制e-r图 3.逻辑结构设计&#xff1a;将e-r图转化为dbms相符合的逻辑结构&#xff0c;db…

模型 拆屋效应

系列文章分享模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。先过分后合理&#xff0c;易被接受。 1 拆屋效应的应用 1.1 高端手表销售案例 一、案例背景 在高端手表销售领域&#xff0c;销售人员面临顾客对价格敏感且购买决策谨慎的挑战。如何引导顾客接受较高…

Windows系统下Pycharm+Minianaconda3连接教程【成功】

0.引言 PycharmMinianaconda3开发组合的好处 优点类别具体优点描述环境管理便捷独立环境创建 环境复制与共享Miniconda3可创建多独立Python环境&#xff0c;支持不同版本与依赖&#xff0c;避免冲突。 能复制、分享环境配置&#xff0c;方便团队搭建相同开发环境。依赖管理高…

4、pytest常用插件

pytest 是一个功能非常强大的测试框架&#xff0c;支持丰富的插件系统。插件可以扩展 pytest 的功能&#xff0c;从而使测试过程更加高效和便捷。以下是一些常用的 pytest 插件及其作用&#xff1a; pytest-cov: 作用: 提供测试覆盖率报告&#xff0c;帮助你了解代码的表现情况…

python每日十题(10)

在Python语言中&#xff0c;源文件的扩展名&#xff08;后缀名&#xff09;一般使用.py。 保留字&#xff0c;也称关键字&#xff0c;是指被编程语言内部定义并保留使用的标识符。Python 3.x有35个关键字&#xff0c;分别为&#xff1a;and&#xff0c;as&#xff0c;assert&am…

Clio:具备锁定、用户认证和审计追踪功能的实时日志记录工具

在网络安全工具不断发展的背景下&#xff0c;Clio 作为一款革命性的实时日志记录解决方案&#xff0c;由 CyberLock Technologies 的网络安全工程师开发&#xff0c;于 2025 年 1 月正式发布。这款先进的工具通过提供对系统事件的全面可见性&#xff0c;同时保持强大的安全协议…

内核编程十三:进程状态详解

进程如同数字世界中的生命体&#xff0c;诞生时被系统母体赋予初始资源&#xff0c;在CPU的脉搏中呼吸&#xff0c;于内存的疆域里生长。它睁开线程之眼观察世界&#xff0c;伸出系统调用之手与环境互动&#xff0c;时而如幼童般单纯执行指令&#xff0c;时而如哲人般陷入阻塞沉…

GitLab 中文版17.10正式发布,27项重点功能解读【一】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…

哈尔滨工业大学DeepSeek公开课人工智能:大模型原理 技术与应用-从GPT到DeepSeek|附视频下载方法

导 读INTRODUCTION 今天继续哈尔滨工业大学车万翔教授带来了一场主题为“DeepSeek 技术前沿与应用”的报告。 本报告深入探讨了大语言模型在自然语言处理&#xff08;NLP&#xff09;领域的核心地位及其发展历程&#xff0c;从基础概念出发&#xff0c;延伸至语言模型在机器翻…

web爬虫笔记:js逆向案例十一 某数cookie(补环境流程)

web爬虫笔记:js逆向案例十一 某数cookie(补环境流程) 一、获取网页数据请求流程 二、目标网址、cookie生成(逐步分析) 1、目标网址:aHR0cHM6Ly9zdWdoLnN6dS5lZHUuY24vSHRtbC9OZXdzL0NvbHVtbnMvNy9JbmRleC5odG1s 2、快速定位入口方法 1、通过脚本监听、hook_cookie等操作可…

WPF ControlTemplate和DataTemplate

在 WPF 中&#xff0c;ControlTemplate 和 DataTemplate 是两个非常重要的概念&#xff0c;它们分别用于定义控件的外观和数据对象的显示方式。以下是关于它们的详细讲解&#xff0c;包括定义、作用、使用场景以及实现示例。 1. ControlTemplate 1.1 定义 ControlTemplate 定…

Qt窗口控件之浮动窗口QDockWidget

浮动窗口QDockWidget QDockWidget 用于表示 Qt 中的浮动窗口&#xff0c;浮动窗口与工具栏类似&#xff0c;可以停靠在主窗口的上下左右位置&#xff0c;也可以单独拖出来作浮动窗口。 1. QDockWidget方法 方法说明setWidget(QWiget*)用于使浮动窗口能够被添加控件。setAllo…

游戏引擎学习第180天

我们将在某个时候替换C标准库函数 今天我们要进行的工作是替换C标准库函数&#xff0c;这是因为目前我们仍然在使用C语言开发&#xff0c;并且在某些情况下会调用C标准库函数&#xff0c;例如一些数学函数和字符串格式化函数&#xff0c;尤其是在调试系统中&#xff0c;我们使…

深度学习PyTorch之动态计算图可视化 - 使用 torchviz 生成计算图

序号系列文章1深度学习训练中GPU内存管理2深度学习PyTorch之数据加载DataLoader3深度学习 PyTorch 中 18 种数据增强策略与实现4深度学习pytorch之简单方法自定义9类卷积即插即用5深度学习PyTorch之13种模型精度评估公式及调用方法6深度学习pytorch之4种归一化方法&#xff08;…

K8S学习之基础四十五:k8s中部署elasticsearch

k8s中部署elasticsearch 安装并启动nfs服务yum install nfs-utils -y systemctl start nfs systemctl enable nfs.service mkdir /data/v1 -p echo /data/v1 *(rw,no_root_squash) >> /etc/exports exports -arv systemctl restart nfs创建运行nfs-provisioner需要的sa账…

Go红队开发—CLI框架(一)

CLI开发框架 命令行工具开发&#xff0c;主要是介绍开发用到的包&#xff0c;集成了一个框架&#xff0c;只要学会了基本每个人都能开发安全工具了。 该文章先学flags包&#xff0c;是比较经典的一个包&#xff0c;相比后面要学习的集成框架这个比较自由比较细化点&#xff0…

eclipse [jvm memory monitor] SHOW_MEMORY_MONITOR=true

eclipse虚拟机内存监控设置SHOW_MEMORY_MONITORtrue D:\eclipse-jee-oxygen-2-win32-x86_64\workspace\.metadata\.plugins\org.eclipse.core.runtime\.settings org.eclipse.ui.prefs (文件比较多&#xff0c;别找错了&#xff09; SHOW_MEMORY_MONITORtrue 重启 -xms 1024…

量子计算与人工智能的融合:下一代算力革命

1. 引言&#xff1a;算力需求的飞速增长与量子计算的潜力 在信息技术飞速发展的今天&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到我们生活的方方面面&#xff0c;从智能助手到自动驾驶&#xff0c;再到医疗诊断&#xff0c;AI 的应用场景日益广泛。然而&#xf…