android屏幕适配

1.基本概念

1.1 px

简单说,像素就是表示一个点的RGB颜色;这个点,是数学上的概念,是没有大小的;但是屏幕显示一个像素是需要大小的,具体大小是屏幕尺寸除以屏幕分辨率

1.2 屏幕分辨率

屏幕分辨率就是屏幕最多能显示多少个像素,如果屏幕最多能显示1080 * 1920个像素,屏幕大小是3 * 5英寸的,那么每个像素占用(3/1080) * (5/1920)的大小。一般情况下屏幕宽高比和像素宽高比是相等的,

1.2 ppi, dpi

屏幕上每英寸上点的数量,我们叫做DPI(dots per inch),因为屏幕上面每个点对应一个像素,所以也有叫PPI;两者大部分情况可以混用,有时候又不一样。当DPI小的时候,每个点的物理尺寸就变大(点的大小理解为 DPI 分之一 英寸;比如DPI是160,每个点就是 1/160 英寸);所以要解决屏幕颗粒大的问题,提高DPI值就可以了。但DPI提高后,又出现了另外一个问题:同样像素的Bitmap在新的屏幕上看起来小了。假设把DPI从160提高到320,原来160像素在新屏幕上的大小只有原来的一半。

1.3 dp,sp

  • 因为在不同dpi下,相同像素下长度不一样,android引入了dp(density independent pixel),sp(Scale-independent Pixel)作为长度单位。简单粗暴直接规定一英寸就是160dp,即1dp=1/160inch;android内部帮我们做了1dp对应多少像素的换算,即(px=dp*(dpi/160)),即1dp在dpi为160的设备上对应1px,在320dpi上对应2px。如此保证在相同dp下,在不同屏幕密度下显示一样的长度。
  • sp和dp很类似但唯一的区别是,Android系统允许用户自定义文字尺寸大小(小、正常、大、超大等等),当文字尺寸是“正常”时,1sp=1dp=1/160inch,而当文字尺寸是“大”或“超大”时,1sp=1sp*scale>1/160inch。类似我们在windows里调整字体尺寸以后的效果——窗口大小不变,只有文字大小改变。

1.3.1 dp的缺陷

  • dp解决了大小一致的问题,没解决比列的问题;如果我们设定控件的宽是160dp,在宽是3inch的屏幕上占比是1/3,在宽是4inch的屏幕上占比是1/4。
  • 不精确;android会将实际dpi进行修正 然后根据density=dpi/160算出density,而px=density * dp;由此可知不是精确的,因为会修正。如实际屏幕密度为321dpi,参考下表知修正后的dpi为480,density为3。
    名称 代表分辨率 范围 修正 density
    mdpi 320x480 120dpi~160dpi 160dpi 1
    hdpi 480x800 160dpi~240dpi 240dpi 1.5
    xhdpi 720x1280 240dpi~320dpi 320dpi 2
    xxhdpi 1080x1920 320dpi~480dpi 480dpi 3
    xxxhdpi 480dpi~640dpi 640dp 4
  • 和美工的设计搞不对应。如设计师的图片基准是1080 * 1920,单位是px,如果图标是60px*60px,我们不能直接写60dp * 60dp,要根据屏幕密度换算成相应的dp。

2.宽高限定符适配

2.1好处

宽高限定符解决了比列,不精确和 美工设计稿不对应三大问题。

2.2使用

做法就是穷举市面上所有的Android手机的宽高像素值:


image.png

设定一个基准的分辨率,其他分辨率都根据这个基准分辨率来计算,在不同的尺寸文件夹内部,根据该尺寸编写对应的dimens文件。
比如以480x320为基准分辨率

宽度为320,将任何分辨率的宽度整分为320份,取值为x1-x320
高度为480,将任何分辨率的高度整分为480份,取值为y1-y480

那么对于800480的分辨率的dimens文件来说,
x1=(480/320)
1=1.5px
x2=(480/320)*2=3px

image.png

这个时候,如果我们的UI设计界面使用的就是基准分辨率,那么我们就可以按照设计稿上的尺寸填写相对应的dimens引用了,而当APP运行在不同分辨率的手机中时,这些系统会根据这些dimens引用去该分辨率的文件夹下面寻找对应的值。这样基本解决了我们的适配问题,而且极大的提升了我们UI开发的效率,

2.3缺陷

  • 需要精准命中才能适配,比如1920x1080的手机就一定要找到1920x1080的限定符,否则就只能用统一的默认的dimens文件了。而使用默认的尺寸的话,UI就很可能变形,简单说,就是容错机制很差。
  • 不适用于sp,当更改系统的字体大小时,字体大小不会改变。因为本质上还是用的px。
  • 包体积大。因为市面上不同宽高的屏幕很多,这里尽可能的适配所有的话,会增大包的体积,采用这种方式包体积一般增大400kb~500kb

3.代码适配

3.1基本原理

image.png

3.2常用的百分比库

android-support-percent android官方的现已经弃用
[AndroidAutoLayout]
(https://github.com/hongyangAndroid/AndroidAutoLayout)鸿洋的 已停止维护
上面两个库都已经停止维护,现在推荐用ConstraintLayout替代。

3.3缺陷

  • 第三方的控件无效
  • 老项目更改繁琐
  • 设计图不匹配

4.最小宽度限定符

4.1 好处

  • 解决了比列
  • 教精确 如果有对应不上的情况,会向下找,这样的话失去了一部分精确性
  • 对应美工设计稿。因为将屏幕分成美工给定的等分

4.2 使用

smallestWidth适配,或者叫sw限定符适配。指的是Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),然后根据识别到的结果去资源文件中寻找对应限定符的文件夹下的资源文件。
这种机制和上文提到的宽高限定符适配原理上是一样的,都是系统通过特定的规则来选择对应的文件。
举个例子,小米5的dpi是480,横向像素是1080px,根据px=dp(dpi/160),横向的dp值是1080/(480/160),也就是360dp,系统就会去寻找是否存在value-sw360dp的文件夹以及对应的资源文件。


image.png

smallestWidth限定符适配和宽高限定符适配最大的区别在于,前者有很好的容错机制,如果没有value-sw360dp文件夹,系统会向下寻找,比如离360dp最近的只有value-sw350dp,那么Android就会选择value-sw350dp文件夹下面的资源文件。这个特性就完美的解决了上文提到的宽高限定符的容错问题。
这套方案是上述几种方案中最接近完美的方案。
首先,从开发效率上,它不逊色于上述任意一种方案。根据固定的放缩比例,我们基本可以按照UI设计的尺寸不假思索的填写对应的dimens引用。
我们还是以375个像素宽度的设计稿为例,在values-sw360dp文件夹下的diemns文件应该怎么编写呢?这个文件夹下,意味着手机的最小宽度的dp值是360,我们把360dp等分成375等份,每一个设计稿中的像素,大概代表smallestWidth值为360dp的手机中的0.96dp,那么接下来的事情就很简单了,假如设计稿上出现了一个10px*10px的ImageView,那么,我们就可以不假思索的在layout文件中写下对应的尺寸。


image.png

而这种diemns引用,在不同的values-sw<N>dp文件夹下的数值是不同的,比如values-sw360dp和values-sw400dp,
image.png

image.png

当系统识别到手机的smallestWidth值时,就会自动去寻找和目标数据最近的资源文件的尺寸。

其次,从稳定性上,它也优于上述方案。原生的dp适配可能会碰到Pixel 2这种有些特别的手机需要单独适配,但是在smallestWidth适配中,通过计算Pixel 2手机的的smallestWidth的值是411,我们只需要生成一个values-sw411dp(或者取整生成values-sw410dp也没问题)就能解决问题。
smallestWidth的适配机制由系统保证,我们只需要针对这套规则生成对应的资源文件即可,不会出现什么难以解决的问题,也根本不会影响我们的业务逻辑代码,而且只要我们生成的资源文件分布合理,,即使对应的smallestWidth值没有找到完全对应的资源文件,它也能向下兼容,寻找最接近的资源文件。

4.3 缺陷

  • 不适配android3.2一下版本。其是android3.2以后引入的
  • 包体积过大。大约会增大300kb到800kb左右

5.density适配

今日头条开放出来的方案

5.1优点

  • 解决比列问题
  • 解决设计图匹配问题
  • 很精确
  • 不影响包体积

5.2使用

5.2.1原理

image.png

从dp和px的转换公式 :px = dp * density 可以看出,如果设计图宽为360dp,想要保证在所有设备计算得出的px值都正好是屏幕宽度的话,我们只能修改 density 的值:


image.png

5.3缺陷

  • 如果有用到第三方库控件,则不适用。因为修改了系统的density值之后,整个布局的实际尺寸都会发生改变。

6.其它(待更新)

参考:
Android 屏幕适配方案
一种极低成本的Android屏幕适配方式
Android 目前最稳定和高效的UI适配方案

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,807评论 6 518
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,284评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 169,589评论 0 363
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,188评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,185评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,785评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,220评论 3 423
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,167评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,698评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,767评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,912评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,572评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,254评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,746评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,859评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,359评论 3 379
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,922评论 2 361