1名词解释:
PPI:Pixels Per Inch也叫像素密度,所表示的是屏幕每英寸所拥有的像素数量。
PPI = √(长度像素数² + 宽度像素数²) / 屏幕对角线英寸数
分辨率:例如 480 * 800 就是说 我的屏幕横向有 480个像素点 ,纵向有 800个像素点;
屏幕大小:例如我的是4.0 英寸, 就是指 从屏幕的左上角 到 屏幕的右下角连线长度为4.0英寸(即对角线长度);
px:即像素,1px代表屏幕上一个物理的像素点;
dp:Android发明的长度单位,具体的下边会说。
dip/dp:两者完全相同,只是名字不同而已。在早期的Android版本里多使用dip,后来为了与sp统一就建议使用dp这个名字了。
sp:与缩放无关的像素(Scale-independent Pixel)。sp和dp很类似但唯一的区别是,Android系统允许用户自定义文字尺寸大小(小、正常、大、超大等等),当文字尺寸是“正常”时1sp=1dp=0.00625英寸,而当文字尺寸是“大”或“超大”时,1sp>1dp=0.00625英寸。类似我们在windows里调整字体尺寸以后的效果——窗口大小不变,只有文字大小改变。
density:屏幕密度,表示每英寸有多少个像素点(点密度),它的单位是dpi:dot per inch。density的计算公式见文章最后,需要注意的是,为了方便图片等资源的使用和屏幕尺寸的适配,一般手机厂商会对手机的屏幕密度即dpi按以下几个分类进行舍入操作,取区间的最大值,比如计算出屏幕密度为400的会默认取xxhdpi最大值480。dpi范围:
密度 | |
0dpi ~ 120dpi | ldpi |
120dpi ~ 160dpi | mdpi |
160dpi ~ 240dpi | hdpi |
240dpi ~ 320dpi | xhdpi |
320dpi ~ 480dpi | xxhdpi |
480dpi ~ 640dpi | xxxhdpi |
比如我的一加3手机(分辨率1920*1080,5.5英寸),按照文末的计算公式计算出屏幕密度为400dpi,在程序中执行以下代码计算出的xdpi为403,ydpi为399。
float xdpi = getResources().getDisplayMetrics().xdpi;
float ydpi = getResources().getDisplayMetrics().ydpi;
那么根据公式dp =1080 / (403 / 160)计算得出宽度为428dp,但是实际上,将图像宽度设置为360dp时宽度既已占满屏幕,而360dp对应的dpi即为480,也就是说,手机的实际屏幕密度,一般为我们根据公式计算出的数值在所属区间内取最大值(如400dpi在320dpi ~ 480dpi之间,会取480dpi作默认屏幕密度),也可用公式计算得出,以dp为单位的屏幕宽度需用计算公式:dpWidth = WidthPixels / fdensity;高度同理。
2疑问:
既然已经有px了,Android为何还要发明dp做长度单位?请看下图:
注意上图:对于一个 宽度为5px 的线段,在不同的手机上表现效果不一样。
而我们期望的效果并不是如上图那样的,我们希望5px的线在B屏幕上被缩放,和屏幕A中一样的比例。
如下图:
我们期望的往往是这种效果,所以这条线在屏幕B上,不能是5px,需要重新计算,而这也是Android推出dp单位的原因。
从Android1.6版本开始支持density(对应API Level 4),用于解决应用在屏幕大小不同的硬件上显示匹配的问题。
3,详解
由于谷歌规定,以density为160dpi作为标准,所以最终公式为:
dp = px / ( dpi
假设我的手机屏幕密度(density)为240,屏幕分辨率480px * 854px。
所以,我的手机宽高各是多少dp呢?带入上面红色的公式:
宽度:dp = 480 / (240 / 160) = 320dp
高度:dp = 854/ (240 / 160) = 569.3333dp
假设另有一款手机,屏幕密度(density)为320,屏幕分辨率720px * 1280px 。
宽度: dp = 720 / (320 / 160) = 360dp
高度: dp = 1280 / (320 / 160)=640dp
现在,对于同一张图片,如果我们设置他的宽度为240px,那么在这两部手机上分别显示为屏幕一半宽度和屏幕1/3宽度。
如果我们换成dp的话,比如设置宽度为160dp,那么在两部手机上分别显示为一半宽度和4/9宽度。可以看出,相对于使用px,使用dp的适配效果已经好了很多。
至此,我们可以得出结论,写成dp可以自动适应不同屏幕密度的手机,但是dp不是万能的,因为安卓手机的分辨率和尺寸实在太过繁多。
density (屏幕密度)如何计算? 首先,要明白dpi的含义。density指的就是 一英寸屏幕上 到底有多少个显示点。
所以公式为: dpi = 屏幕对角线像素 / 屏幕尺寸。
4.0是屏幕的大小,980是屏幕对角线像素,所以我手机屏幕密度就为240dpi.