目的
- 什么是屏幕尺寸、屏幕分辨率、屏幕像素密度?
- 什么是dp、dip、dpi、sp、px?它们之间的关系是什么?
- 什么是mdpi、hdpi、xdpi、xxdpi?如何计算和区分?
- 设备屏幕的标准是什么?
基本概念
-
屏幕尺寸
屏幕尺寸指的是屏幕对角线的长度(单位是英寸),1英寸 = 2.54厘米
-
屏幕分辨率
屏幕分辨率是指屏幕上的像素点(单位是px), 如 : 1960(height) * 1080(width)
-
屏幕像素密度
屏幕像素密度是指每英寸上的像素点(单位是dpi,是dot per inch的缩写),与屏幕尺寸以及屏幕分辨率有关
一款设备的屏幕尺寸越小或者分辨率越高,屏幕像素密度越大,反之越小。
单位(px、dp、sp、dpi)
-
sp
即scale independent pixels的缩写,是字体大小的御用单位
-
px
大多数情况下,比如UI设计、Android原生API(如:获取屏幕宽高等)都会以px作为统一的计量单位
-
dp
是density independent Pixels的缩写,翻译过来就是:密度无关像素
-
dpi
密度有关像素,假如一英寸里面有160像素,这个屏幕的像素密度就是160dpi
dpi = sqrt(sqr(width) + sqr(height)) / 屏幕尺寸
density
这是一个密度概念,和dpi相关,用于dp和px之间的换算。
在Android中,规定以160dpi为基准,即 density 1 = 160dpi / 160dpi。
类推,一块每英寸有320像素的屏幕,其density为2,这就是Android系统的density密度计算公式。
- 换算
px = density * dp = (dpi/ 160) * dp
资源文件夹标识(mdpi、hdpi、xdpi、xxdpi)
这些标识用于区分不同屏幕像素密度(dpi)下的资源(drawable、values)。
Android官方标准区分:
这些标准按照 2 : 3 : 4 : 6 : 8 的density比例用于换算。
使用dp单位的缺陷
假设一款屏幕density为3,那么根据density计算公式:
- dpi = density * 160 = 3 * 160 = 480
假设屏幕大小为640 x 360dp,根据计算公式px = density * dp:
- 分辨率为:1920 x 1080px
根据计算公式 dpi = Math.hypot(width, height) / 屏幕尺寸 :
- 屏幕尺寸为4.6英寸
所以在这样的一个设备上,控件宽度为360dp = 360 * 3 = 1080px,则填满横向屏幕。
通过计算公式可以由density推导得到一个标准的屏幕配置,也可以通过屏幕分辨率和尺寸得到density:
- density = dpi / 160 = Math.hypot(width, height) / 屏幕尺寸)/ 160
然而在同一种分辨率下完全可能存在不同尺寸的屏幕,从而造成dpi、density不同,比如:
- density = 3 = 480dpi / 160 = Math.hypot(1080, 1920) / 4.6) / 160
- density = 3.44 = 550dpi / 160 = Math.hypot(1080, 1920) / 4) / 160
这时候360dp在2个屏幕上的效果也就不一致:
- 360dp = 360dp * 3 = 1080px
- 360dp = 360dp * 3.44 = 1238.4px
最后
按照Android标准density计算方式使用下的dp单位,无法满足中国碎片化的Android生态,标准情况下应该是要遵循px = density * dp这一计算公式,但是中国手机厂商根本不遵守这一标准。
总结:
由于相同分辨率的手机设备可以有不同尺寸,导致相同分辨率设备的density不同,从而1dp在这些设备上代表的像素不同。
参考:
[1]. 支持多种屏幕 | Android文档
[2]. 一种极低成本的Android屏幕适配方式 | 今日头条技术团队