Android屏幕适配一二三

一点简单的Android屏幕适配经验分享

Posted by lx8421bcd on April 23, 2016

Android中的dp单位

大家都知道,Android手机有n种型号,也有n种屏幕,不算平板,绝大部分Android手机屏幕是16:9的分辨率。早期的屏幕分辨率有240x160,320x240……这些手机基本已经被淘汰了,仍然在使用这些手机的用户,基本上都是智能机当功能机使用的用户,一般不建议兼容这些机型,会产生相当高的额外成本。目前我们所需考虑的最低屏幕应该就是4寸WVGA(480x800)。
现在Android手机主流的尺寸从4寸~7寸不等,大多数手机的尺寸集中在5寸左右,Android不仅屏幕尺寸多样,就算是同一尺寸下的屏幕也会有不同的分辨率,比如同是5寸屏,可能有的机型为1080p,有的机型为2K,这就造成了一个问题,即由于屏幕密度的不同,像素这个单位不能再确定设计实际的物理尺寸了。
举例来说,现有同是5寸的两台手机,一台分辨率为1080p(1080 x 1920),一台为2k(1536 x 2560),显然后者的屏幕密度是要高于前者的,如果这时有个按钮声明宽度为200px,那么在1080p的屏幕上,这个按钮的宽度大概是屏幕宽度的18%,然而在2k的屏幕上这个按钮的宽度则会降到屏幕宽度的13%,而在480*800的手机上这个按钮的宽度又会占屏幕宽度的41%,这样的变化显然是无法容忍的,所以在Android上,有dp这么一个单位,也就是密度无关像素。

dp具体的计算公式是这样的:

​ dp = px / (ppi / 160)

​ ppi = √(screenWidth^2 + screenHeight^2) / screenInches

通过这种方式,可以计算在在一个确定了尺寸和分辨率的屏幕上,像素标注对应的dp长度。
使用dp的目的,就是为了让这个单位与实际尺寸关联起来,在不同密度和不同尺寸的屏幕上,固定大小的dp与物理尺寸尽量保持一致。
dp单位的使用保证了同样一个按钮,在4寸720p、5寸1080p和5寸2k的屏幕上有着相近的实际尺寸。这也就带来了另外一个问题,实际尺寸在小屏太挤大屏太宽怎么办?

小屏?大屏?

紧接上面提出的问题,也是很多人说Android屏幕千差万别难适配的“原因之一”,然而平心而论,iOS不难么?iPhone 5是4寸屏,iPhone 6p是5.5寸屏,一样要考虑大屏和小屏的适配问题。
在小屏大屏的问题上,我们要了解一点共识:
小屏手机显示较少的内容,更方便单手持握时操作,大屏手机显示更多的内容
用户买大屏手机,是为了看到更多的内容,而不是为了看到放大的内容; 同样用户买小屏手机,只是为了更方便单手操作而不是为了看缩小的内容。大屏手机就应该比小屏手机显示更多的内容,小屏手机显示的比大屏 紧凑也是理所应当的。
之所以提到这个,是我在工作过程中,曾经遇到过一种歪风:“我保证所有Android手机的内容显示比例都跟设计稿差不多,就是适配的好了,工作就完成了……”,这种做法,适配工作量很大,而且小屏手机体验极差,无论手机屏幕大小怎样,人的手指就那么大,如果一个在5寸屏幕上刚刚好的按钮,等比缩放到4寸屏上,可能用户想要准确点中它就非常吃力。同样,字体如果等比缩放,小屏手机用户阅读会很吃力。
在适配问题上我们要明确一点,屏幕适配不仅是开发的事,同样是设计师的事,对于难以进行屏幕适配的设计,我们要驳回,要商讨怎么改进,而不是被动的接受下来抱怨。

远古时代的歪门邪道

如果研究过Android屏幕适配的内容,或者看过一些年代比较久远的项目,估计会看到这样一种适配方法
老方法
它在每个分辨率下都生成了一套dimens.xml文件,生成一套“nPX=”mdp””的适配文件,然后无脑将设计稿上的px值填入xml布局文件中,以此来让不同屏幕都有这相同比例的UI显示。
在Android上古时代,这套适配方案是适用的,可以在屏幕差异不大,ppi相近的屏幕上较好的实现等比缩放的效果,然而在高ppi屏幕出来之后,继续使用这样的适配方案则是自寻死路。
正如文章开头的例子,5寸1080p和5寸2k手机,都是5寸,那么一套设计在5寸手机上显示的比例应该是一样的。然而采用这种“歪门邪道”的适配方案,系统去取dimen值时则将会分别从1080x1920和1440x2560中取,从而在同是5寸的手机上得到完全不同的显示效果。这种问题,在大屏手机上非常常见,低端大屏1080p,高端大屏2k甚至4k,使用这种方案适配将会带来一场灾难。

如果你身边有老古董在做项目中还在继续使用这种适配手段,请务必阻止。

等比缩放

那么我们在开发过程中是不是完全不用考虑等比缩放呢,并不是,有些复杂的UI是需要在大小屏幕上都按比例显示的。比如下图这个老虎机界面
老虎机
如果不对这个弹窗进行等比缩放,就会出现在小屏手机上UI超出屏幕,大屏手机上UI过小的问题。 等比缩放有两种解决方案,一个是在UI创建时,计算屏幕比例使用setScale对UI进行缩放,这种方法适用于一些简单的没有什么交互的控件;另一个是使用百分比布局,比如PercentageLayout和ConstraintLayout。控件的使用方法这里就不详细叙述了。

美术只给我iOS设计稿怎么办

我相信这个问题是很多开发者经常抱怨的事情,也经常被人拿来论证Android体验差,但是说实话,这点我在工作以来,真没感觉到有多么麻烦,Android和iOS的交互语言本身就没有那么大差别,都在相互借鉴。

iOS设计稿怎么用
以手机端为例,美术的设计稿大部分是以iPhone 6(4.7inch, 1334x750)作为标准。这样一个设计稿上一个100px的按钮,我们需要对应成多少dp呢?
Android没有这样尺寸的设备,我们找一个参数最接近且使用比较广泛的设备作为基准
我以Pixel为例(5.0inch, 1920x1080)
按比例将iPhone 6设计稿控件的宽度转换到Pixel上

W(android) / ScreenW(android) = W(iOS) / ScreenW(iOS)
W(android) = (W(iOS) / ScreenW(iOS)) / ScreenW(android)

根据dp、px换算公式,可以算出W(android)的dp值

Wdp(android) = W(android) / (441ppi / 160)

通过上面的计算,如果一个View在iPhone 6上的宽度是100px,那么其在Pixel上的dp值大概是52dp 由于比例是固定的,那么我们可以基本得出,iPhone 6上的标注 除以2 等于 Pixel上的 dp 标注。
在实际应用中也是如此

  • 一般iPhone 6及其切图在iOS设计中为@2x,对应Android的xhdpi,标注值除以2即可得到dp值
  • 一般iPhone 6 plus及其切图在iOS设计中为@3x,对应Android的xxhdpi,标注值除以3即可得到dp值

这样的换算基本是准确的,细微的误差可以在设计验收时微调。