dp是和像素密度无关的
px:pixel,像素
density:密度,dpi,ppi
dpi和ppi这两个是密度单位,不是度量单位,而这两个恰恰是我们换算中重要的分母。简单理解一下:
- ppi (pixels per inch):图像分辨率 (在图像中,每英寸所包含的像素数目)
- dpi (dots per inch): 打印分辨率 (每英寸所能打印的点数,即打印精度)
px = dip * density / 160,则当屏幕密度(即dpi或者ppi)为160时,px = dip
px = dp * (dpi / 160),所以density就是dpi或者ppi,即dot per inch, 翻译过来为每英寸的点数(dp和dip相同,但和dpi不同)
dp为我们程序设计时给控件设置的长度(和像素无关,),而density或者说是dpi是屏幕硬件有关的,是作为用户或者开发者无法改变的。这里的dpi是归一化后的dpi,可能值只有120(low)、160(medium)、240(high)、320(xhigh)四种,并不是设备实际的真实的dpi值,选用的就近原则,比如我的设备的真实dpi是252,算px的时候要选择靠近252的240来计算,320 * (240 / 160) = 480像素。
尽管Android系统对待dp这事上,将所有设备视为四种:120(low)、160(medium)、240(high)、320(xhigh),在160dpi上,160dp就是1英寸,在240dpi上,160dp还是1英寸(计算出来的结果为240pix,在240dpi的设备上,为一英寸),120dpi和320dpi也还是1英寸,虽然他们占用的像素数不一样,但是最终显示出来的效果都是占用了屏幕上1英寸的范围。这套体系其实是非常合理的,一个宽为160dp的按钮,它在所有设备上占用的物理尺寸应该是一样大才合理,这样他们对人眼所形成的张角才一样大,观看或者阅读的感觉才一致(姑且不考虑按钮的背景是否一样细致)。这应该是Android系统引入dp概念的原因。
根据 google 的建议,TextView等控件的字号最好使用 sp 做单位,而且查看TextView的源码可知Android默认使用sp作为字号单位。将dip作为其他控件的单位。