前言:

对于 Android 来说,屏幕适配一直是一个不能忽略的点,毕竟手机厂商太多,屏幕碎片化太严重。虽然本人对于适配也看过了一些文章,但是一直是一知半解,而且在实际的项目中也接触得少,所以一直处于梦游状态。因为我有时候就会很懵,给我一张图,我应该放在哪个目录里面?drawable、drawable-mdpi... 哪个目录,怎么才能确定呢?
所以,以这个问题为出发点,我结合了其他的博客,写下了这篇文章,希望能够尽量解决一下有关屏幕适配的疑惑!!!

以下所有概念都是针对 Android 适配来说的,如在其他领域有歧义,勿喷。
文章若有问题,欢迎指正。


一、相关概念

1、像素

对于屏幕适配,必须先清楚一个概念,那就是像素,即px、pixel,是画面中最小的点(单位色块)。像素的大小是没有固定长度值的,是相对的,不同设备上1个单位像素色块的大小是不一样的。在说像素的时候,也可以说成像素点,这样更加直观。

2、分辨率

分辨率=画面水平方向的像素值 * 画面垂直方向的像素值。通俗的说,就是 水平像素点数量 * 垂直像素点数量
分辨率可以分为两方面:屏幕分辨率图像分辨率

(1)屏幕分辨率:
假设屏幕尺寸大小固定,分辨率是1080 × 1920 px,那么就表示,这块屏幕,在水平方向上有 1080 个像素块(点),在竖直方向上有 1920 个像素块一般情况下默认前面的数值表示水平方向,后面的表示竖直方向);而如果是同样的屏幕尺寸,分辨率为 1024 × 768 px,则此时的像素块就比 1080 × 1920 px 的大一些,但是显示效果也就没那么细腻了。

(2)图片分辨率
一张图片分辨率如果是 500 x 200 px,假设显示的屏幕分辨率为 1500 x 600 px,这张图片在屏幕上按 1:1 放大时,就占用屏幕 500 x 200 个像素块的面积。
在同一台设备上,图片分辨率越高,这张图片1:1放大时,图片面积越大;图片分辨率越低,这张图片1:1缩放时,图片面积越小。(可以理解为图片的像素点和屏幕的像素点是一个一个对应的)。

3、屏幕的尺寸

屏幕尺寸指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米。主要注意不同屏幕对角线的长度一样,但是宽、高不一样的情况。

4、dp\dip、sp

dip 和 dp 是一个意思(注意,不是 dpi ),都是 Density Independent Pixels 的缩写,是一种密度无关像素。在 Android 开发中,这个就是最常见的。

sp,即 scale-independent pixels,与 dp 类似,但是可以根据文字大小首选项进行放缩,是设置字体大小的御用单位。

5、dpi 与 ppi

dpi 即 Dots Per Inch,为每英寸像素块(点)的个数。
ppi是 Pixel per inch,每英寸像素数,针对显示器的设计时,dpi=ppi。

与 Android 屏幕适配有关的笔记
上图中的屏尺寸是屏幕对角线的长度,单位为英寸。

这里,只需要记住,对于 Android 开发来说,dpi 与 ppi 是等价的即可。且 dpi ( ppi ) 是用来描述手机屏幕的。


二、px、dp、dpi 的关系

在 Android 中,规定以 160dpi (即 160ppi)为基准,1dp=1px,如果密度是 320dpi,则 1dp=2px。这句话的意思就是说,如果屏幕的 dpi( 160ppi ) 为 160,则在这个屏幕里面,1dp 就代表 1px;如果屏幕的 dpi 为 320( 320ppi ),则在这个屏幕里面,1dp 就代表 2px。
因此,1dp 是根据屏幕的 ppi 值动态的等值于对应的 px 值的。这就是为什么 Android 中使用 dp 来进行适配的原因。


三、mdpi、hdpi、xdpi、xxdpi 目录的作用

mdpi、hdpi、xdpi、xxdpi 用来修饰 Android 中的 drawable 文件夹及 values 文件夹,用来区分不同像素密度下的图片和 dimen 值。(右边的为手机像素密度范围)
与 Android 屏幕适配有关的笔记

进一步说,如果一个手机的屏幕为 160ppi(dpi),即 mdpi 的,正常情况下,应用会去 drawable-mdpi 目录下去取相应的图片,当然如果 values 也设置来类似于 drawable 一样众多类型的目录,也会是根据屏幕的 ppi 去自动匹配对应目录下的资源文件,layout 也是如此。
详见:多分辨率适配常用目录

上面说的是正常情况下,那什么是非正常情况呢,比如有一张图片,只适配了 drawable-mdpidrawable-xhdpi 目录,即在 drawable-hdpi 目录中没有,那么如果一个手机是 hdpi 的,讲道理会去 drawable-hdpi 目录下取图片,但是图片不存在啊,会怎么样呢,难道就不显示这张图片吗?当然不会了,如果对应的目录下没有,就会去存在该图的且最相近的且相比之下质量更高的目录下去取图片(都没有的话,则会去默认的无后缀 drawable 目录下取),即在 drawable-xhdpi 中去取,而不是在 drawable-mhdpi 中取。

另外,如果一个高质量的图片本应该放在高 dpi 的 drawable 目录下,如应该放在 drawable-xhdpi 中的图片如果放在了 drawable-mhdpi 中,那么在使用的时候就有可能造成 OOM。


四、一张固定像素的图片应该放哪里呢?

如果有一张 800 * 600 px 的图片,应该放在哪个 drawable 目录下最合适呢?

其实,对于这个问题呢,我也很蛋疼,因为我找了好久,也在 Stack Overflow 上提问了,但是没有得到一个确定的答复,然后也看了很多博客,下面我将尽自己的所能把自己认为的答案总结出来:

个人觉得,刚才这个问题是没有确定的答复的,因为如果真的是完善的适配的话,肯定是会有几套相应质量的图片的,那张 800 * 600 px 的图片在 hdpi 至 xxdpi 这几个目录下都是可以存放的(因为一般只适配这几个目录),如果放到了某一个目录下,则其他目录也要根据对应的比例,来放相应的图片:

mdpi hdpi xdpi xxdpi
1 1.5 2 3

但是,实际上,有时候为了减小 apk 的大小,只做一套图,放在drawable-xxdpi文件夹中。具体细看这里。


五、并非完美的 dp

与 Android 屏幕适配有关的笔记
截图自:Android 屏幕适配方案,详情亲参见该文。


参考链接:

1、分辨率和像素是什么关系?
2、Android屏幕适配全攻略(最权威的官方适配指导)
3、dp 这个单位是安卓发明的么?为什么 px=dp*(dpi/160)?
4、google 开发文档 - 支持不同密度
5、多分辨率适配常用目录
6、那些值得你去细细研究的Drawable适配
7、google 开发文档 - 支持多种屏幕
8、Android 屏幕适配:最全面的解决方案
9、Android 屏幕适配方案

相关文章: