本帖最后由 大山哥哥 于 2017-3-30 17:06 编辑
在安卓中,说起长度单位,大家都不陌生。基本每个页面里面都大量使用到了长度单位,大家也能说出来常用的一些长度单位。dp、sp、px……而且,大家也基本粗略的知道使用dp、sp这些单位能解决一些屏幕适配的问题。然而为什么是这个样子,各个单位之间又是如何换算的。在不同设备上为什么表现出不同的像素长度等问题大家可能没有深入研究过,看到转换公式中的density、dpi、dip、dp、px就头疼,不知所云。接下来我们就来一起来揭开安卓中这些长度单位的面纱。
首先我们先解释一下一些基本概念,然后再进入计算。
dip:Density independent pixels,设备无关像素,也就是我们常用的dp。
px:像素,屏幕上的一个像素点。
dpi(注意和dip区分):dots per inch,直接来说就是一英寸多少个像素点。常见取值 120,160,240。一般称作像素密度
density:直接翻译的话貌似叫 密度。常见取值 1.5,1.0,2.0等和标准dpi的比例(160px/inc)。一般取值为1的时候即在当前设备下,1dp = 1px。
分辨率:横纵2个方向的像素点的数量,常见取值 480X800 ,320X480,这个比较好理解。
屏幕尺寸:屏幕对角线的长度。电脑电视同理。4英寸、5.5英寸、6英寸等
屏幕比例:因为只确定了对角线长,2边长度还不一定。所以有了4:3、16:9这种,这样就可以算出屏幕边长了,用到的比较少。
了解完基本概念,我们再来对照一下代码中的一些变量的含义。在Android里面,获取一个窗口的metrics,直接用.的方式看成员变量。可以发现
[AppleScript] 纯文本查看 复制代码 metrics.density;
metrics.densityDpi; densityDpi就是我们刚才说的dpi,每个手机上都可能不一样,和分辨率以及屏幕尺寸相关。
density就是Dpi/(160像素/英寸)后得到的值,dpi的单位是像素/英寸,比较符合物理上面的密度定义,所以做完除法之后的density就是一个没有单位的倍数值,就是一个相对于标准dpi的比率。
好的,到现在我们已经把基本的概念都搞定了,接下来看一看单位的换算。首先是dpi的计算,dpi刚才说了,就是dots per inch,每英寸的像素数。一个4英寸的手机,说的是屏幕对角线的长度为4英寸,根据分辨率用勾股定理可以算出来对角线的像素数,除以英寸数就是dpi了。即一个320*480的4英寸手机,dpi = sqrt(320²+480²)/4 ≈ 144.2。
接下来是我们最熟悉的dp 与 px的计算,px就不说了,就是像素的个数。而对于dp,这里有个非常方便的公式。
dp = (DPI/(160像素/英寸))*px = density*px。
假设dpi是240像素/英寸,那么density就是1.5,那么就是 dp=1.5px。我们可以根据自己已知的条件选择最方便快速的公式使用。那为什么要除以160,160是哪来的呢?这个在Google的官方文档中有给出了解释,因为第一款Android设备(HTC的T-Mobile G1)是属于160dpi的,所以就把这个dpi作为了标准,就是这么简单。 实际上,定160为标准还有更深一层的含义,也就是计算方便。Android Design里把主流设备的dpi归成了四个档次,120 dpi、160 dpi、240 dpi、320 dpi。实际开发当中,我们经常需要对这几个尺寸进行相互转换(比如先在某个分辨率下完成设计,然后缩放到其他尺寸微调后输出),一般按照dpi之间的比例即2:1.5:1:0.75来给界面中的元素来进行尺寸定义。也就是说如果以160dpi作为基准的话,只要尺寸的DP是4的公倍数,XHDPI下乘以2,HDPI下乘以1.5,LDPI下乘以0.75即可满足所有尺寸下都是整数pixel。但假设以240dpi作为标准,那需要DP是3的公倍数,XHDPI下乘以1.333,MDPI下乘以0.666,LDPI下除以2,而以LDPI和XHDPI为基准就更复杂了,所以选择160dpi最方便。
好的,现在我们可以理解为什么我们在布局的时候最好要用dip,不要用px了吧。因为Android开源的特性,导致Android系统可能运行在各种各样的设备上,不同的设备的尺寸、分辨率都可能是不同的。即使分辨率相同,都是1280*720的手机,有的也是5英寸,还有的是5.5英寸。这就导致使用px作为长度单位,在不同的设备上显示的效果是不同的,这就导致了我们的UI会在不同用户眼中出现不同程度的变形,甚至显示的很诡异。而使用dp作为单位,在不同的设备上显示出来的效果始终是一致的,这样就会大大减少用户UI变形的情况。
最后,还有一个常用的单位叫sp,这个单位一般用在文字大小上。dp和sp都是安卓的开发单位,dp是长度单位,sp是字体单位。sp与dp类似,但是可以根据用户的字体大小首选项进行缩放。Android系统允许用户自定义文字尺寸大小(小、正常、大、超大等等),当文字尺寸是“正常”时1sp=1dp,而当文字尺寸是“大”或“超大”时,1sp>1dp。一般情况下可认为sp=dp就行了。现在大多数的UI设计会基于720P,xhdpi条件下,即1dp=2px。所以大家只需要将px值除以2就可以得到界面中应该设置的长度和字体大小了。
|
|