Android 屏幕各种参数的介绍和学习
经常被 Android 设备纷繁的屏幕搞得是晕头转向,下面就梳理一下 Android 中的相关概念。
一、概念
1.1 屏幕大小
屏幕大小是手机对角线的物理尺寸,单位是:英寸(inch),1 inch =2.54 cm(厘米) 。例如现在手机大多都是 “6.0寸” 以上的屏幕,这个就是对角线的尺寸,6.0(inch) X 2.54(cm)/ 1 (inch)= 15.24(cm)
1.2 屏幕分辨率
分辨率就是手机屏幕的像素点数,一般描述为:纵像素 * 横像素,如 2240 * 1080,就是在纵方向上有2240个像素点,在横方向上有1080个像素点。
1.3 屏幕像素密度
屏幕像素密度(dpi,dots per inch;或 PPI ,pixels per inch),就是每英寸的像素点,数值越高显示越细腻。假如一部手机的分辨率是 1080*1920 ,屏幕大小是5英寸,那么此屏幕的密度是多少呢?通过宽1080和高1920,根据勾股定理,得出对角线的像素大约是2203,那么用2203/5=440,440dpi就是屏幕的像素屏幕密度。
1.4 实际密度和系统密度
这里其实将的还是上面的 屏幕像素密度 ,不过是换了一种说法。
实际密度:就是我们自己算出来的密度,这个密度代表了屏幕真实的细腻程度,如上述例子中的440dpi 就是实际密度,说明这块屏幕每寸有440个像素。5英寸1080*1920 的屏幕密度是440,而相同分辨率的4.5英寸屏幕是490。如此看来,屏幕密度会出现很多数值,呈现严重的碎片化。而密度有时 Android 屏幕将界面进行显示的依据,那么 Android 是如何适配这么多屏幕的呢?其实,每部手机屏幕都有一个初始固定密度,这些数值是120、160、240、320、480,我们权且称为“系统密度”。大家发现规律没有?相隔数值之间是2倍的关系。一般情况下,240*320的屏幕是低密度120dpi,即 ldpi ;320*480的屏幕是中密度160dpi,即 mdpi ;480*800的屏幕是高密度240dpi,即 hdpi ;720*1280的屏幕是超高密度320dpi,即xhdpi ;1080*1920的屏幕密度是超超高密度480dpi,即 xxhdpi;
在具体的 Android 项目下,这些表示不同屏幕密度(不同分辨率)用来修饰 Android 中 drawable 文件夹以及 value 文件夹,用来区分不同像素密度下的图片和 dimen 值,所以在不同 drawable 文件夹下图片的 densityDpi 的值也是不同的 。这会导致用 BitmapFactory 的 decodeResource创建 Bitmap 时,其加载到内存的大小不一样。(详见 深入理解Android Bitmap的各种操作)
Google官方指定按照下列标准进行区分:
名称
|
像素密度范围
|
mdpi
|
120dpi ~ 160dpi
|
hdpi
|
160dpi ~ 240dpi
|
xhdpi
|
240dpi ~ 320dpi
|
xxhdpi
|
320dpi ~ 480dpi
|
xxxhdpi
|
480dpi ~ 640dpi
|
1.5 dp
dp 也可以写成dip(density independent pixel),即密度无关的像素。比如,一张宽和高均为100dp的图片在 320 *480 和480*800的手机上,“看起来”是一样大,实际上,它们的像素值并不一样。dp正是这样一个尺寸,不管这个屏幕的密度是多少,屏幕上相同dp的大小的元素看起来始终差不多大。另外,文字尺寸使用 sp,即 scale independent pixel 的缩写,与 dp 类似,是设置字体大小的御用单位。在 Android 中,系统密度为160dpi的中密度手机屏幕为基准屏幕,即320*480的手机屏幕。在这个屏幕中:1dp = 1px。
100dp在320*480(mdpi,160dpi)中是100px。那么100dp在480*800(hdpi,240dpi)的手机上,根据160与240的比例关系,100dp实际覆盖了150px。因此,如果你为mdpi手机上提供了一张100px的图片,这张图片在hdpi手机上就会拉伸至150px,但是他们都是100dp。要注意一点的就是:dp和px的换算要以系统密度为准,720*1280的系统密度为320,320*480的系统密度为160,320/160=2,那么在720*1280中,1dp = 2px。同理,在1080*1920中,1dp = 3px。有一个dp和px换算的比例公式:ldpi : mdpi :hdpi:xdpi:xxdpi = 3:4:6:8:12,我们发现相隔数字之间还是2倍的关系。计算的时候,以 mdpi 为基准。如果以 mdpi 为基准比例为:
dpi : mdpi :hdpi:xdpi:xxdpi = 0.75:1:1.5:2:3
二、从系统中获取相关参数和转换
2.1 DisplayMetrics
这个类是 Android 提供的记述屏幕有关信息的一种类,诸如其尺寸、屏幕像素密度等。
获取这个对象的方法:
DisplayMetrics metrics = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); DisplayMetrics metrics=activity.getResources().getDisplayMetrics(); Resources.getSystem().getDisplayMetrics();
这个类中有几个比较重要的属性:
public int widthPixels; public int heightPixels; public float density; public int densityDpi; public float scaledDensity; public float xdpi; public float ydpi;
在 DisplayMetrics 中,density 和 densityDpi 这个两个的线性关系:
density
|
1
|
1.5
|
2
|
3
|
3.5
|
4
|
densityDpi
|
160
|
240
|
320
|
480
|
560
|
640
|
2.2 TypedValue
TypedValue 是 Android 提供单位转换的类,这个类是工具类,作为一个动态容器,它存放一些数据值,这些值主要是 resource 中的值。TypedValue 类把对应的值转化为实际屏幕上的点值,也就是像素值,总体来说作用:把 Android 系统中的非标准度量尺寸转变为标准度量尺寸(Android 系统中的标准尺寸是 px,即像素)。非标准单位:dp 、in、mm、pt、sp
典型应用为:
TypedValue.applyDimension(int unit, float value, DisplayMetrics metrics)
其中,第一个参数 unit 是你需要转换的单位,第二个参数 value 是你需要得到的单位数值,第三个参数 metrics 封装了屏幕区域各种属性。
例如:我要得到一个 20dp 在当前设备上对应的 px 值:
float px_value = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,20,context.getResources().getDisplayMetrics());
还有其他类型:
TypedValue.applyDimension()方法的功能就是把非标准尺寸转换成标准尺寸: dp->px: TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, context.getResources().getDisplayMetrics()); in->px: TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_IN, 20, context.getResources().getDisplayMetrics()); mm->px: TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 20, context.getResources().getDisplayMetrics()); pt->px: TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PT, 20, context.getResources().getDisplayMetrics()); sp->px: TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, context.getResources().getDisplayMetrics());
不积跬步无以至千里,不积小流无以成江海。让我们默默前行,不蹉跎岁月,不辜负自己。突然想到家园的歌词:冰雪早已覆盖我的足迹,远方的炊烟摇曳温暖的召唤,风儿无法吹断我回望的视线,家园好像永远征途漫漫。是啊,我们人生也是征途漫漫。
站在巨人的肩膀上:
UI设计师不可不知的安卓屏幕知识
Android屏幕适配及DisplayMetrics解析