1.大屏适配的屏幕屏幕几种方式
2.聊聊获取屏幕高度这件事
3.SmallestWidth限定符适配 - dimens.xml 文件生成
大屏适配的几种方式
1. rem方案
根据不同屏幕大小动态调整html根节点的fontsize。
2. vw/vh方案
依据设计稿计算相对百分比。适配适配
3. scale 方案
若设计稿为*(:9),源码源码存在两种方案:
3.1 按宽度缩放
3.2 动态计算网页的屏幕屏幕宽高比,决定根据宽度比率还是适配适配高度比率进行缩放
4.相关开源组件库
4.1 autofit.js
autofit.js基于比例缩放原理,通过动态调整容器的源码源码国外源码发布网宽度和高度来实现全屏填充,避免元素的屏幕屏幕挤压或拉伸。autofit.js提供了一种简单而有效的适配适配方法来实现网页的自适应设计,尤其适合需要在不同分辨率和屏幕尺寸下保持布局一致性的源码源码应用场景。
安装:
配置:
源码地址
4.2 v-scale-screen
大屏自适应容器组件,屏幕屏幕适用于大屏项目开发,适配适配实现屏幕自适应。源码源码可根据宽度自适应、屏幕屏幕高度自适应、适配适配宽高等比例自适应,源码源码全屏自适应(会存在拉伸问题)。如果是React开发者,可以使用r-scale-screen。
安装:
配置:
源码地址:
4.3 FitScreen
一种基于缩放的大屏自适应解决方案的基本方法,基于设计草图的像素尺寸,通过缩放进行适配,一切变得简单。
支持vue2、vue3以及react,适用于任何框架,只需少量代码。
安装:
配置:
源码地址:
聊聊获取屏幕高度这件事
说起获取屏幕高度,易语言电脑检测源码或许你有所理解,但这个高度范围究竟指的是应用显示区域的高度,还是手机屏幕的高度呢?我们先来回顾一下平时使用获取高度的方法:
以上三种方法的效果一致,只是写法略有不同。
或许你使用的是这种方法:
这个方法在系统版本大于等于Android 4.2时,会使用getRealMetrics(getRealSize)来获取屏幕高度。那么这里发生了什么?为什么会这样呢?
其实在Android 4.0时,引入了虚拟导航键。如果你继续使用getMetrics之类的方式获取高度,获取的高度会去除导航栏的高度。
由于在4.0和4.2之间并没有getRealMetrics这个方法,所以当时甚至需要添加适配代码:
现在应该没有人还在适配4.4甚至5.0以下的机型了吧?所以历史的包袱可以放下了。
上面方法名都是getScreenHeight,但这个高度范围到底和你需要的是否一致呢?这需要开发时注意。我的习惯是ScreenHeight指应用显示的高度,不包括导航栏(非全屏下),RealHeight指包含导航栏和状态栏的高度(getRealMetrics)。
PS:以前也使用过AndroidUtilCode这个工具库,里面将前者方法名定义为getAppScreenHeight,后者为getScreenHeight。也是很直观的方法。
下文中我会以自己的习惯,使用ScreenHeight和RealHeight来代表两者。
我印象中华为手机很早就使用了虚拟导航键,如下图(来源):
比较特别的是,当时华为的java版监控系统源码导航栏还可以显示和隐藏,注意图中左下角的箭头。点击可以隐藏,上滑可以显示。即使这样,使用getScreenHeight也可以准确获取高度,隐藏了ScreenHeight就等于RealHeight。
上述的这一切在“全面屏”时代到来之前,没有什么问题。
小米MIX的发布开启了全面屏时代(年底),以前的手机都是:9的,记得雷布斯在发布会上说过,他们费了很大的力气说服了谷歌去除了:9的限制(从Android 7.0开始)。
全面屏手机是真的香,不过随之也带来适配问题。首当其冲的就是刘海屏,各家有各自的获取刘海区域大小的方法。主要原因还是国内竞争的激烈,各家为了抢占市场,先于谷歌定制了自己的方案。这一点让人想起了万恶的动态权限适配。
其实在刘海屏之下,还隐藏一个导航栏的显示问题,也就是本篇的重点。全面屏追求更多的显示区域,随之带来了手势操作。在手势操作模式下,结巴分词 源码解析四导航栏是隐藏状态。
本想着可以和上面提到的华为一样,隐藏获取的就是RealHeight,显示就是减去导航栏高度的ScreenHeight。然而现实并不是这样,下表是我收集的一些全面屏手机各高度的数据。
ScreenHeight一栏中括号内表示显示导航栏时获取的屏幕高度。
大致的规律总结如下:
其中vivo手机,屏幕高度加状态栏高度大于真实高度( + > )。本以为差值是刘海高度,但查看vivo文档后发现,vivo刘海固定dp(px),也还是对不上。
一加6最奇怪,三种设置模式。使用侧边全屏手势时底部有一个小条,NavigationBar高度变为。( + = + = )也就是说这种模式也属于有导航栏的情况。
这时如果你需要获取准确的ScreenHeight,只有通过RealHeight - NavigationBar来实现了。
所以首先需要判断当前导航栏是否显示,再来决定是否减去NavigationBar高度。
先看看老牌的判断方法如下:
此方法通过比较ScreenHeight和RealHeight是否相等来判断。如果对比上面表中的数据,那只有OPPO Find X可以判断成功。也有一些方法通过ScreenHeight和RealHeight差值来计算导航栏高度。cab文件解压器源码显然这些方法已无法再使用。
所以搜索了一下相关信息,得到了下面的代码:
可以看到包含了华为、小米、vivo、oppo、三星甚至诺基亚的判断。这就是适配的现实状况,不要妄想寻找什么通用方法,老老实实一个个判断吧。毕竟幺蛾子就是这些厂家搞出来的,厂家魔改教你做人。
这种方法在上面的测试机中都亲测准确有效。
不过这个判断方法不够严谨,比如其他品牌手机使用此方法,那么结果都是false。用这样的结果来计算高度显得不够严谨。
根据前面提到问题发生的原因是全面屏带来的(7.0及以上)。所以我们可以先判断是否是全面屏手机(屏幕长宽比例超过1.以上),然后判断是否显示导航栏,对于不确定的机型,我们还是使用原先的ScreenHeight。尽量控制影响范围。
我整理的代码如下(补充了一加、锤子手机判断):
有人会问,这些key都是哪里来的?毕竟我在厂商文档也没有翻到。
我能想到的办法是查看SettingsProvider,它是提供设置数据的Provider,分有Global、System、Secure三种类型,上面代码中可以看到不同品牌存放在的类型都不同。我们可以通过adb命令查看所有数据,根据navigation等关键字去寻找。比如查看Secure的数据:
或者:
这样如果有上面兼容不到的机型,可以使用这个方法适配。也欢迎你的补充反馈。
费了这么大的劲获取到了准确的高度,可能你会说,还不如直接获取ContentView的高度:
这个结果和上述计算的高度一致,唯一的限制是需要在onWindowFocusChanged之后调用,否则高度为0。这个我们可以根据实际情况自行选用。
第二种情况就是状态栏强制为黑色。这里我怀疑因为这个设置,导致在有刘海的手机上,ScreenHeight不包含状态栏高度。
最糟糕的是第三种,隐藏后状态栏在刘海外。例如Redmi K在开启后,ScreenHeight为,RealHeight为,而关闭时为和。这下连万年不变的RealHeight也变化了,这太不real了,大家自行体会。不过目前发现未影响适配方案,不知其他手机如何。
对于是否隐藏刘海,其实也是有各家的判断的,比如小米:
getSystem源码如下:
它不受资源覆盖的影响,我们可以通过它将值转换回来。
本篇看似聊的获取高度这件事,其实伴随导航栏的发展演进,核心是是如何判断导航栏是否显示。
通过上面的介绍,总结一下就是在“全面屏时代”,如果你想获取屏幕高度,就不要使用ScreenHeight了。否则会出现UI展示上的问题。而且这种问题,线上也不会崩溃,难以发现。以前在支付宝中就发现过PopupWindow弹出高度不正确的问题,过了好久才修复了。
至于屏幕宽度,也不清楚随着折叠屏、环绕屏的到来会不会造成影响。但愿不要吧,碎片化越来越严重了。
最后,如果本文对你有启发有帮助,点个赞可好?
SmallestWidth限定符适配 - dimens.xml 文件生成
在Android开发中,适配不同分辨率和像素密度的屏幕是一项关键任务。本文将深入探讨如何利用SmallestWidth限定符适配方案生成一系列dimens.xml文件,以实现跨设备的界面一致性。首先,我们需要理解屏幕分辨率和像素密度的概念。
屏幕分辨率通常以像素数表示,Android手机常见的分辨率包括x、x、x、x等。像素密度则表示每英寸像素的数量,是衡量屏幕清晰度的重要指标。
假设有一部手机分辨率为x像素,屏幕大小为5英寸,那么其像素密度可以通过以下计算得出:
像素密度 = (屏幕宽度像素数 / 屏幕宽度英寸数) * = ( / 5) * = dp
在设计界面时,设计师通常会提供最小宽度,以便开发人员可以针对不同设备生成相应的dimens.xml文件。此文件包含了不同设备所需的尺寸参数,确保界面在各种设备上都能保持一致的布局。
为了生成这些文件,我们首先需要获取设计图中最小宽度的值(单位为dp)。然后,以这个基准值为基础,自动生成所有设备对应的dimens.xml文件。这个过程可以通过使用ScreenMatch插件来实现。该插件能够根据提供的基准宽度,生成适配各种分辨率和像素密度的设备的文件。
然而,ScreenMatch插件在生成文件时存在一些限制。例如,它默认可能没有适配最小宽度为dp的设备,以及对于最小宽度为.与.dp的设备,插件可能无法实现完全适配。这是因为插件默认对数值进行了四舍五入处理。为了解决这些问题,我们对插件源代码进行了优化,并生成了新的插件。
在使用插件时,首先确保在项目的默认values文件夹中存在一份dimens.xml文件。然后,安装ScreenMatch插件,并在项目中选择适配的模块。通过插件生成一系列的dimens.xml文件,以满足不同设备的需求。最后,根据设计图填写最小宽度基准值,并设置需要适配的设备最小宽度dp值,完成适配过程。
需要注意的是,配置文件screenMatch.properties中包含了适配设置,如最小宽度基准值、默认适配的最小宽度值、需要适配的最小宽度值(包含小数时保留四位小数)、忽略的最小宽度值等。通过修改这些值,可以自定义适配方案以满足特定需求。
总结起来,生成适配dimens.xml文件的主要步骤包括获取设计图最小宽度、选择合适的插件、生成文件、配置适配参数、以及根据设计图调整布局尺寸。通过这些步骤,可以有效地实现界面在不同设备上的适应性。