为什么Android需要进行屏幕适配?
由于Android系统的开放性,任何用户、开发者、OEM厂商、运营商都可以对Android进行定制,修改成他们想要的样子。
但是这种“碎片化”到底到达什么程度呢?
在2012年,OpenSignalMaps(以下简称OSM)发布了第一份Android碎片化报告,统计数据表明,
2012年,支持Android的设备共有3997种。
2013年,支持Android的设备共有11868种。
2014年,支持Android的设备共有18796种。
……
市场上Android手机的屏幕尺寸繁多,甚至宽高比例也不一样。而设计师给出的视觉稿,只是针对一种屏幕尺寸给出的,如何移植到不同分辨率的设别上,同时使的视觉效果一致呢?
需要解决的问题
需要解决的核心问题是什么?
- 让不同分辨率,不同尺寸的手机。打开同一个应用,看到的内容是一样多的。
我买了大屏手机,就是要看更多的内容,这样我的大屏手机还有什么用呢?
- 是的,你必须接受。如果更大的屏幕可以看到更多的内容,那无疑对开发者带来巨大的工作量。
真的是所有手机看到的内容完全一样多吗?
- 不是的,主流应用会让不同手机在宽这个维度上看到的内容一样多;而在高这个维度上,则是能放多少方多少。
屏幕适配所需要了解的基本概念
- px: 像素数,没什么好说的
- ppi: 买手机的时候,经常会听到这个词。其在手机屏幕中指的是像素密度,是物理上的概念,它是客观存在的不会改变。
- dpi: 像素密度,指的是在系统软件上指定的单位尺寸的像素数量,一般都取整数。它往往是写在系统出厂配置文件的一个固定值。dpi 是参考了 ppi 后,人为指定的一个值,用来保证某一个区间内的 ppi 在软件上都使用同一个 dpi 值。这样会有利于我们的UI适配。
- dp: 设备独立像素,是 Android 中的概念。
- density: 代表 1dp 占当前设备多少像素。计算方式: density = dpi/160,用作 px 与 dp 的转换。
转换公式:
1 | density = dpi / 160 |
比如,几部相同分辨率不同尺寸的手机的ppi可能分别是是430,440,450,那么在Android系统中,可能dpi会全部指定为480.这样的话,dpi/160就会是一个相对固定的数值,这样就能保证相同分辨率下不同尺寸的手机表现一致。
适配方案进化史
方案一:在manifest文件中指定设计原型图的长宽,然后在view onMeasure 的时候,根据设备具体的宽高和原型图的宽高等比缩放,侵入型太强,对于一些自定义View的支持不是很好,而且宽高都缩放,很容易变形。
方案二:smallestWidth适配,只适配宽度,适配性极好,但是会引入包大小问题,因为要兼容的机型太多了,同时侵入性也有点高,各处都需要引用dp值,不能直接写具体数据,一旦切换方案,也在可接受范围。
方案三:指定设计原型图大小,依然是按照设计图上的px写dp值,但是不是有一个 px = density * dp
的公式嘛,修改系统的 density 值就好了,侵入性小,应该是目前最好的一种方案。