我们先来了解一下基本的概念
屏幕尺寸 :屏幕对角线长度,如图。(换算单位:1英寸 ≈ 2.54厘米)
Density 指像素密度。 假如同样是1080*1920的屏幕,屏幕越小当然视觉效果会更好更清晰,像素密度也就更大。
DPI 全称 Density Per Inch , 每英寸的像素个数,平常使用不多。
(绝大部分手机的DPI计算方式: DPI = density × 160 )【为啥是160? 因为第一款Android设备:HTC的T-Mobile G1,是属于160dpi的】
DP 也称 DIP 全称 Density independent pixels 密度无关像素。
来两个例子:
栗子一号 :手机屏幕 1080 * 1920 通过系统方法 metrics.density 得知 Density 值为3.0。
那么可以得知:
该手机屏幕的DPI = 3.0 × 160 = 480DPI
要填充满屏幕宽度1080px,需要 1080 ÷ 3.0 = 360dp
【有兴趣的小伙伴可以试下:查看手机屏幕宽度px,然后获取手机Density值,之后可以通过画一根带颜色的横线测试一下,是否是设置成计算出的dp正好填满,而略低于此dp是即将填满状态 】
栗子二号 : Pad,手机屏幕1600 * 2560 ,通过系统方法 metrics.density 得知 Density 值为2.55。
可以得知:
该手机屏幕的DPI = 2.55 × 160 = 408DPI (正常情况下,Pad屏幕点阵密度会低于手机,所以一半Pad的展示效果并没有手机那么细致)
要填充满屏幕宽度1600px,需要 1600 ÷ 2.55 = 627dp (亲测,在设置了一条625dp的彩线后,线条刚好在屏幕右侧漏了个小小缺口)
下面来看下怎么做屏幕适配吧。
在xml中写布局,一般都是给出精确的dp值。如图:
从那两个甜甜的栗子可以得知:在全宽627dp的设备上和全宽360dp的设备上,使用固定dp的展示效果差别是很大的。
所以下面再来两个橙子:
橙子One :通过代码配置dp。【 此方式适用于个别控件需要设置大小的情况。】
我们自定义一个单位转换的方法,因为总宽的dp我们不知道,所以我们以百分比来计算。假设需要指定宽度为屏幕的80%。
好,代码来了:
/** percent 值在 0-1之间 float类型 */
fun getDp(percent: Float) : Float {
return ScreenUtils.getScreenWidth() * percent / ScreenUtils.getScreenDensity()
}
/** percent 值在 0-1之间 float类型 【代码动态配置大小,都是以px计算的, 直接返回px】 */
fun getPx(percent: Float) : Int {
return ScreenUtils.getScreenWidth() * percent.toInt()
}
注意:代码中配置大小,都是转换成px计算的。所以我们直接使用px。不过得到需要的DP值的方法已经给你们了。
橙子Two : Studio 的一个插件:ScreenMatch 。可直接在插件库中搜索。【 网络不好的,就多试几次 】
ScreenMatch特点: 自动生成不同屏幕的尺寸资源,会根据安装设备的屏幕DPI 决定使用哪一组dimen资源。
安装完ScreenMatch插件,随便一个module上右键,按下图操作一次。
选择screenMatch资源包放在哪个module下。然后点确定。执行成功之后会重打开项目。
然后就可以看到,对应Module下已经有了相应的资源文件,而主目录下也有了screenMatch的配置文件。
ScreenMatch.properties 包含一些配置,其他配置采用默认就好,看看下面三个配置项 :
base_dp: 是设定屏幕划分成多少等份的。
由于我们组美工给的图 Android和iOS是同一套,尺寸标注是以iOS屏幕:750px计算。所以是把屏幕750等分,这里就设置750. 这样省的我们自己转换标注值了。
设置成750等分后,不管在什么屏幕上展示,只要引用这个750dp,宽度就正好等于屏幕。当然,也可以指定为其他值,如 base_dp = 360。
match_dp: 这个属性 是指适配哪些特定的dp。采用默认设置就好。如果遇到特殊dp值需要精确适配的,就加入到这个参数后面。在重新执行ScreenMatch后,会新生成对应dp的资源。
627dp的适配就是我新加的,然后就自动生成了 values-sw727dp 这个文件夹。
ignore_dp: 是忽略哪些特定dp的设备,这里可以看出,它几乎忽略了Pad以上等大屏dp的设备。
我们的栗子中使用了一个全宽627dp的设备。如果我们不特意写在 match_dp 里面,ScreenMatch会自动寻找最适合的dp资源, values-sw600dp 和 627dp最接近。所以会优先使用此资源。
项目根目录下的 ScreenMatch_example_dimens.xml 是样本参数。只需要把这里面的参数复制到values目录下的dimens.xml 文件中。然后执行ScreenMatch操作。【如果是老项目,注意去除重复】
values资源文件夹是原始资源文件夹。所有values-sw***dp文件夹都是依赖 values目录下的dimens.xml 生成的。
所以如果需要新加一个dimens值,在values下的dimens.xml 中添加,然后在Module上右键执行ScreenMatch 就会自动在所有values-sw***dp文件夹中都新增一个参数。
怎么样 ?妈妈再也不用担心屏幕适配问题了。
PS:屏幕适配在手机屏范围内还是挺适用的。屏幕越大,界面相当于按比例放大,当到达Pad屏这个程度大小的时候,界面就会显得不够美观。
如果对字体也做了适配,就更明显了。
当然,这种等比例放大,也会保证界面各个控件保持协调。总体来说有利有弊,但利大于弊。
来源:oschina
链接:https://my.oschina.net/u/3673815/blog/3196614