【大道至简】官方兼容到android13+的获取系统屏幕高度, statusbar,navBar

android在屏幕高度和app高度,statusbar, navigationbar的高度处理上,迭代了好多版本。
android11, android12都有新的api和过时的api标记。

涉及的api类似如下:
windowManager,defaultDisplay, Context.display, DecorView, windowInsets, Compat兼容库, getRealSize, getSize,
currentWindowMetrics, maximumWindowMetrics, 通过resources获取资源id navigation_bar_height等等等等。

网上的帖子跟api一样,实现的五花八门太多了。

花了2天时间,终于找到了官方,而且最合适的方案:
全网似乎都没有这么简洁和准确的方案了:
implemention “androidx.window:window:1.2.0” 引入后,写上下面2个函数:

//随意调用,官方出品最精简,最准确。
fun Activity.getScreenFullSize() : Pair<Int, Int> {val m = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this)//computeMaximumWindowMetrics(this) 区别就是多屏,类似华为推上去的效果。不分屏就是一样的。return m.bounds.width() to m.bounds.height()
}/**
* 获取当前的statusBar的高度和navigationBar高度。如果在onCreate,onStart, onResume调用,必须经过一轮View.post之后。
* 如果你明确知道activity已经ok则直接调用。
*/
fun Activity.currentStatusBarAndNavBarHeight() : Pair<Int, Int>? {val insets = ViewCompat.getRootWindowInsets(window.decorView) ?: return nullval nav = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottomval sta = insets.getInsets(WindowInsetsCompat.Type.statusBars()).topreturn sta to nav
}

接下来介绍一下:

想要屏幕高宽

getScreenFullSize() 即 WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(activity)

无需等待界面渲染成功,即在onCreate就可以调用,而且里面已经做了低版本兼容,感谢jetpack window库
获取的就是整个屏幕的高度。包含了statusBar,navigationBar的高度一起。与adb shell wm size一致。
这个方法100%可靠。虽然我们看api上描述说低版本(由于navigationBar可能获取不到)近似值,但也是最接近最合理的值,不会是0的。所以这个函数就是目前集大成者。
点击computeCurrentWindowMetrics进入查看源码:

 val bounds = if (Build.VERSION.SDK_INT >= VERSION_CODES.R) {currentWindowBounds(activity) //往下就是wm.currentWindowMetrics.bounds} else if (Build.VERSION.SDK_INT >= VERSION_CODES.Q) {computeWindowBoundsQ(activity) //反射Configuration windowConfiguration bounds} else if (Build.VERSION.SDK_INT >= VERSION_CODES.P) {computeWindowBoundsP(activity) //反射Configuration windowConfiguration bounds} else if (Build.VERSION.SDK_INT >= VERSION_CODES.N) {computeWindowBoundsN(activity) //display realSize + navigationHeight Id获取} else {computeWindowBoundsIceCreamSandwich(activity)}

由此可见,这个就是集大成者。
大家放心使用getScreenFullSize,WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this),来获取屏幕的高宽。官方出品最精简,最准确。

想要SystembarHeight和navBarHeight

大家一般都见过这个代码:

fun Window.transparentStatusBar(isBlackStatusBarTextColor: Boolean? = null,isBlackNavigationBarTextColor: Boolean? = null,crossinline insetsBlock: (insets: WindowInsetsCompat,statusBarsHeight: Int,navigationBarHeight: Int) -> WindowInsetsCompat = {insets, _, _ -> insets}
) {ViewCompat.setOnApplyWindowInsetsListener(decorView) { _, insets ->val bottom = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottomval top = insets.getInsets(WindowInsetsCompat.Type.statusBars()).topinsetsBlock.invoke(insets,top,bottom)}WindowCompat.setDecorFitsSystemWindows(this, false)statusBarColor = Color.TRANSPARENTif (isBlackStatusBarTextColor != null || isBlackNavigationBarTextColor != null) {WindowCompat.getInsetsController(this, decorView).apply {if (isBlackStatusBarTextColor != null) {isAppearanceLightStatusBars = isBlackStatusBarTextColor}if (isBlackNavigationBarTextColor != null) {isAppearanceLightNavigationBars = isBlackNavigationBarTextColor}}}
}

我们经过用上述代码来做沉浸式。就是程序在statusBar之下,也可以在navigationBar之下。更加延展。
这里其实有2个注意点:
这个函数如果不调用
WindowCompat.setDecorFitsSystemWindows(this, false) 对于constraintLayout是不会回调的。他默认fitsystemWindow。
我们如果仅仅ViewCompat.setOnApplyWindowInsetsListener是不一定有回调的。

所以使用注意事项:

  1. 你如果做了沉浸式,即调用了WindowCompat.setDecorFitsSystemWindows(this, false) + setOnApplyWindowInsetsListener,则可以在回调监听获取
        val bottom = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom //navBarHeightval top = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top //statusbarHeight
  1. 你如果没有做沉浸式或者setOnApplyWindowInsetsListener不生效,那么调用currentStatusBarAndNavBarHeight().
    即,ViewCompat.getRootWindowInsets(window.decorView)
    他的说明文档,写了,必须在view Attach到屏幕上,即view.post的执行,就是attach之后运行的。有兴趣可以研究View的post逻辑源码。
    如果明确已经准备好,则无需post了。也就是在onCreate,onResume使用该函数必须post。

  2. 唯一缺点就是,不能动态监听。这也不能说是缺点,他本意就是一次获取。使用场景就是这样。如果你要动态监听,还是类似实现透明一样,通过WindowCompat.setDecorFitsSystemWindows(this, false) + setOnApplyWindowInsetsListener监听实现。

其他备注:

windowManager.currentWindowMetrics和MaximumWindowMetrics的区别:
max永远是屏幕大小。
current就是当前窗口,其实也是包含了statusBar和navigationBar的。但是当多窗口模式,或者分屏,比如华为有这个悬浮应用功能,获取到的current就是变化后的。
请添加图片描述

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

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

相关文章

分布式系统的一致性与共识算法(二)

Consitency 背景 如买最后一张车票&#xff0c;两个售票处分别通过某种方式确认过这张票的存在。这时&#xff0c;两家售票处几乎同时分别来了一个乘客要买这张票&#xff0c;从各自"观察"看来&#xff0c;自己一方的乘客都是先到的&#xff0c;这种情况下&#xf…

思科模拟器学习1--Vlan Trunk

实验说明&#xff1a;将三台电脑的vlan 加到一台交换机里面&#xff0c;为了验证什么是虚拟局域网&#xff0c;把一个设备隔成三个空间&#xff0c;三个电脑互相不能通讯&#xff1b;目的是&#xff1a;vlan 1的通讯不可以向vlan 2传送&#xff0c;就是消息传送互不干扰的&…

解决Android Studio Gradle下载慢的问题

安卓 gradle-7.5-bin.zip 下载慢 https://mirrors.cloud.tencent.com/gradle/7.x.x 找到对应匹配版本 把下载的文件直接复制到 C:\Users\Administrator.gradle\wrapper\dists\gradle-x.x\ 中对应版本目录下&#xff0c;例如需要下载 gradle-2.14.1-all.zip&#xff0c;则下载好…

【Pytorch】torch.nn.conv2d

这个函数和我们之前提到的【Pytorch】6.torch.nn.functional.conv2d的使用的作用相似&#xff0c;都是完成CV领域的卷积操作&#xff0c;这里就不在过多赘述 torch.nn.conv2d的使用 打开pytorch的官方文档&#xff0c;我们可以看到 torch.nn.conv2d包含了若干参数 in_channe…

考研数据结构:栈与队列

栈与队列 栈Stack 栈的结构体定义及基本操作。 #define MaxSize 50 typedef struct {int data[MaxSize];//栈中存放数据类型为整型int top;//栈顶指针 }Stack; void InitStack(Stack& S) {//初始化栈S.top -1; } int IsEmpty(Stack S) {//判断栈是否为空if (S.top -1)…

一文读懂 Pencil 积分,打开 Pencils Protocol 生态权益大门

近日&#xff0c;Scroll 生态项目 Penpad 近期将品牌全新升级为 Pencils Protocol &#xff0c;在升级后&#xff0c;其从一个 Scroll 生态的原生 LaunchPad 平台进一步拓展为集 Staking、Vault 以及 Shop 等功能于一体的全新生态。全新的品牌升级不仅让 Pencils Protocol 生态…

ubuntu18.04系统安装pangolin

1. 安装pangolin依赖项 ctrlaltt 打开终端&#xff0c;依次输入下面的命令 sudo apt update sudo apt upgrade sudo apt install libglew-dev cmake libboost-dev libboost-thread-dev libboost-filesystem-dev libeigen3-dev -y 2.在终端中输入下面的命令&#xff0c;克隆…

2024 年第一季度全球互联网中断事件

2024 年第一季度伊始&#xff0c;互联网发生了多起中断事件。陆地和海底电缆的损坏在多个地方造成了问题&#xff0c;而与持续中地缘政治冲突相关的军事行动影响了其他地区的连接。 几个非洲国家以及巴基斯坦的政府下令关闭互联网&#xff0c;主要针对移动网络连接。 被称为Ano…

Pyqt中QThread传递自己定义的参数、类、函数

Pyqt中QThread传递自己定义的参数、类、函数 1 pyqt中Qthread传递自己定义的参数2 pyqt中Qthread传递自己定义的类3 pyqt中Qthread传递自己定义的函数4 pyqt中Qthread内部定义自己的函数5 pyqt中Qthread传递参数到内部定义自己的函数 1 pyqt中Qthread传递自己定义的参数 在PyQ…

Android开发adb命令使用大全

Android开发中&#xff0c;adb&#xff08;Android Debug Bridge&#xff09;是一个多功能命令行工具&#xff0c;它允许你与连接的Android设备进行通信。以下是一些常用的adb命令及其用途的详细列表&#xff1a; 基本设备管理 adb devices&#xff1a;列出所有连接的设备和模拟…

(四)Spring教程——控制反转或依赖注入与Java的反射技术

IoC的底层实现技术是反射技术&#xff0c;目前Java、C#、PHP 等语言均支持反射技术。 在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够获取到这个类的所有属性和方法&#xff1b;对任意一个对象&#xff0c;都能够调用它的任意方法和属性&#xff08;包括私有的方法…

python的标准数据类型

四、标准数据类型 1、为什么编程语言中要有类型 类型有以下几个重要角色&#xff1a; 对机器而言&#xff0c;类型描述了内存中的电荷是怎么解释的。 对编译器或者解释器而言&#xff0c;类型可以协助确保上面那些电荷、字节在程序的运行中始终如一地被理解。 对程序员而言…

vLLM推理服务库

一、定义 定义与目的为什么Cache只存储K、V&#xff0c;而不存储Q&#xff1f;为什么vllm和HF推理结果不一致&#xff1f;vLLM 实现原理pagedAttention 实现原理模型部署demo 二、实现 定义与目的 目的&#xff1a;减少显存、提高吞吐量。如何优化KV cache&#xff0c;节省显…

基于大模型训练的数字识别

创作原因 现在写电赛题&#xff0c;题目有识别数字的要求。但使用设备openmv使用模板匹配的算法帧率很低&#xff0c;且识别效果不是很好&#xff0c;于是我们就想到了利用神经网络训练模型来识别数字 正文部分 内容介绍 本文内容是基于openmv使用Edge Impulse训练大模型。…

爬虫工作量由小到大的思维转变---<第七十五章 > Scrapy爬虫回调函数在请求重试中的应用研究

前言&#xff1a; 在Scrapy框架中&#xff0c;利用回调函数进行请求重试的实践方法与其优劣势&#xff0c;与传统的中间件重试机制进行对比。通过深入分析回调函数的工作原理及其在网络爬虫项目中的应用&#xff0c;旨在提高网络爬虫的效率和稳健性。同时&#xff0c;本文将探讨…

服务攻防——应用协议ssh,rsync,proftpd,openssh,libssh

1.口令猜解 ftp-拿来文件传输的 rdp-windows远程连接 3389 ssh-linux远程连接 工具hydra 口令 1.windows 这就爆破成功了&#xff0c;现在&#xff0c;我们就可以ftp爆破&#xff0c;爆破出ftp的密码 爆破出来后 访问 2.ssh Rsync&#xff08;配置不当&#xff0c;未授权…

【Docker】docker-compose简单实战

1、首先要准备好Jar包 docker-compose.yml version: "2.2.4" services:redis:image: rediscontainer_name: redisvolumes:- /redis/data:/data- /redis/redis.conf://usr/local/etc/redis/redis.confnetworks:- kewu-networkkewu:build:context: .dockerfile: dock…

[NOI Online #2 入门组] 未了

[NOI Online #2 入门组] 未了 题目描述 由于触犯天神&#xff0c;Sisyphus 将要接受惩罚。 宙斯命 Sisyphus 推一块巨石上长度为 L L L 的山坡。Sisyphus 匀速向上推的速度为每年 v v v 的长度&#xff08;由于是匀速&#xff0c;故经过 1 2 \frac{1}{2} 21​ 年将能向上…

Gooxi发布最新AI服务器:加速生成式AI落地 更懂AI

近日&#xff0c;Gooxi发布最新训推一体AI服务器&#xff0c;以大容量内存和灵活的高速互连选项满足各种AI应用场景&#xff0c;最大可能支持扩展插槽&#xff0c;从而大幅提升智能算力性能&#xff0c;以最优的性能和成本为企业的模型训练推理落地应用提供更好的通用算力。 AI…

主从Reactor服务器

目录&#xff1a; 目录&#xff1a; 目标&#xff1a; 本文讲解思路&#xff1a; 各模块的功能以及代码&#xff1a; 1.服务器相关模块&#xff1a;服务器模块的功能是对所有的连接以及线程进⾏管理 2.协议相关模块&#xff1a;协议模块是对当前的Reactor模型服务器提供应…