〔两行哥〕致敬AutoLayout,手把手带你适配任意分辨率

本项目已经上传至码云,有兴趣的哥们可以参考。

码云:https://gitee.com/xuzhaoyu/ScreenPixelDemo

场景一:UI拿着一份1334 * 750(参照iPhone 8)的效果图时,各位Androider心里肯定千万个草泥马奔腾,这种分辨率的图能用?简直渣渣啊!放眼当下安卓阵营,1000-2000价位,遍地2K屏幕,遍地“全面屏”,1334*750这种“类720P”分辨率的苹果效果图,安卓百元机都不好意思用,还要我们做的与其一致?

场景二:在5.0寸的1920 * 1080设备上,一个Button的宽度为180dp,大概占屏幕宽度1/2。可是在6.8寸1920 * 1200的某设备上,该Button宽度居然只占了屏幕的1/4到1/3的样子,最终UI和产品验收产品的时候,BBBB,Androider心里同样千万个草泥马。
满满痛点啊!现今安卓阵营高分设备越来越多,屏幕适配刻不容缓,让我们自己动手,丰衣足食。如果您还不了解px,dp,dpi,请先移步补充px,dp,dpi的概念。

不知道诸位是否使用过鸿洋的AutoLayout,简直是安卓碎片化大背景下的屏幕适配的救星。不过可惜的是,AutoLayout已经停止更新很久,而且本身在兼容性上也存在一定问题,比如仅支持三大布局的如下属性:
1.layout_width
2.layout_height
3.layout_margin(left,top,right,bottom)
4.pading(left,top,right,bottom)
5.textSize
其次,Autolayout对部分含有虚拟按键的机型适配不佳。
再者,全面屏(18:9)机型也有很多,如果UI给的基准分辨率比例为16:9,在全面屏机型上会出现画面被拉高的问题。
那么我们该如何做屏幕适配呢?为了更好的兼容性,让我们回到屏幕适配的起点,看看基本的做法:在项目moudle/src/main/res/包下建立对应分辨率包,如values-1920 * 1080,values-1280 * 720等,并在每个包内创建合适的dimen,如下图所示:


图1 添加不同的dimen

当设备的分辨率为1920 * 1080时,就会读取values-1920 * 1080包下的dimen值,当设备分辨率为1280 * 720时,就会读取values-1280 * 720包下的dimen值,以此类推。

这种方式的兼容性毫无疑问是最佳的,而且也几乎不用考虑性能损失。如果采取这种方式进行适配,那么接下来的两个问题是:

1.我们到底有多少种分辨率?也就是要建立多少种values-xxxx*xxxx包?

2.然后又如何给每个包内生成dimen值?

一、主流设备的分辨率

为了保证兼容性,两行哥公司的App搜集了用户设备屏幕尺寸的信息,抓取到的分辨率如下(为期1年左右,近80款):
1440* 2427; 800 * 1217; 1600* 2434; 1024* 720; 1440* 2368; 1440* 2768; 1600* 2461; 1080* 1809; 1080* 2220; 1080* 2076; 1080* 2094; 1080* 1815; 1080* 1919; 1080* 1804; 1080* 2016; 1080* 2030; 720 * 1166; 1920* 1080; 1080* 2160; 720 * 1192; 1280* 720; 800 * 1232; 1080* 2034; 576 * 1024; 621 * 1104; 1080* 1797; 1080* 1803; 1080* 1825; 1080* 1810; 1200* 1920; 800 * 1216; 1200* 1848; 1080* 1848; 1200* 1852; 720 * 1200; 1080* 2040; 720 * 1216; 900 * 1600; 1200* 1830; 1080* 1821; 1152* 1920; 1600* 2560; 1440* 2434; 1600* 2452; 768 * 1184; 768 * 1280; 1536* 2048; 1440* 2792; 936 * 1664; 1080* 1788; 1080* 1794; 1080* 1830; 1080* 1800; 720 * 1208; 320 * 432; 320 * 480; 800 * 1280; 1440* 2416; 1200* 1824; 1080* 1806; 480 * 854; 1200* 1836; 1440* 2560; 1536* 2560; 1440* 2392; 1440* 2408; 1080* 1812; 600 * 976; 720 * 1242; 540 * 960; 1080* 1776; 240 * 320; 480 * 800; 480 * 640; 720 * 1184; 600 * 1024; 1080* 1920; 720 * 1280; 1440 * 2960; 720 * 1440。
那就以此为标准,我们根据上述分辨率建立values-xxxx * xxxx包。

二、生成dimen值

图2 项目结构

这里借用鸿洋的autolayout.jar工具(具体参见http://blog.csdn.net/lmj623565791/article/details/45460089)。
将图中标注的autolayout.jar拷贝至任意目录,在当前目录下打开命令窗口。例如,在windows环境下,在文件管理器中,按住Shift,右键,选择在此处打开命令窗口。在弹出的命令行窗口中,按照如下格式输入命令:

java -jar autolayout.jar defaultWidth defaultHeight targerWidth1,targetHeight1_targerWidth2,targetHeight2_targerWidth3,targetHeight3......

defaultWidth,defaultHeight就是基准分辨率,targetWidth和targetHeight就是目标分辨率,可以有多个目标分辨率。

例如:
UI的效果图基于1334 * 750(基准分辨率),上面有一个宽50px,高20px的控件,那么换算到目标分辨率(1920 * 1080 和 1280 * 720)上的宽高是多少呢?运行如下命令:
图3 命令行
运行完毕你会发现在autolayout.jar所在的路径下生成了一个res文件夹,拷贝到项目中即可。

请先点进去看看res里面有什么,然后再继续阅读。

图4 生成res文件夹

如果我们想把上述1334 * 750分辨率下效果图中宽50px,高20px的控件,适配到我们想要的分辨率中怎么办呢?写控件时的宽高为x50和x20就可以了(或者宽高为x50和y20,但是不建议,见下文),如下图:


图5 控件宽高

稍微看一下,1920 * 1080分辨率下,x20 = 28.8px,x50 = 72px(<dimen name="x20">28.8px</dimen>,<dimen name="x50">72.0px</dimen>),即1920 * 1080 分辨率下宽28.8px,高72px与1334 * 750 分辨率下宽20px,高50px所占屏幕比例一致,做到了完美适配。

那么接下来就把两行哥生成dimen的代码附上,省的各位手敲麻烦:

java -jar autolayout.jar 750 1334 1600,2434_1600,2461_1600,2560_1600,2452_1536,2048_1536,2560_1440,2960_1440,2427_1440,2368_1440,2768_1440,2434_1440,2792_1440,2416_1440,2560_1440,2392_1440,2408_1200,1920_1200,1848_1200,1852_1200,1830_1200,1824_1200,1836_1152,1920_1080,1809_1080,2220_1080,2340_1080,2076_1080,2094_1080,1815_1080,1919_1080,1804_1080,2016_1080,2030_1080,2160_1080,2034_1080,1797_1080,1803_1080,1825_1080,1810_1080,1848_1080,2040_1080,1821_1080,1788_1080,1794_1080,1830_1080,1800_1080,1806_1080,1812_1080,1776_1080,1920_900,1600_800,1217_800,1232_800,1216_800,1280_768,1184_768,1280_720,1440_720,1166_720,1192_720,1200_720,1216_720,1208_720,1242_720,1184_720,1280_600,976_600,1024_576,1024_540,960_480,854_480,800_480,640_320,432_320,480_240,320

如果UI给的效果图是基于1920 * 1080的,那么把上述750(defaultWidth) 1334(defaultHeight)改成1080 1920即可,以此类推。然后参照效果图的标注,标注多少px,在项目中就使用dimen/x多少 或 dimen/y多少。

如果要保证控件宽高比例,建议不要使用y的值,因为现在18:9的屏幕也出来了,如果效果图是16:9,那么在18:9的屏幕中,单位y值已经变大,可能使控件被拉高而变形(不再是效果图中的宽高比),宽高都使用x值即可。如果控件不需要考虑宽高比例,只是需要保证宽高所占屏幕的百分比一致,那么宽使用x,高使用y。请各位读者自行思考琢磨。

三、其他优化

考虑一个问题,生成了这么多的values包,我们放入了app这个module。同时,我们项目也依赖了一些第三方的控件库module,在这些控件module里也有一些xml布局,如果我们想让它也适配屏幕,该如何做?难道我们在每个第三方控件库module的src/main/res/都拷贝这么多的values包吗?其实不用,可以参照Demo中的架构:


图6 独立module进行适配

新建一个module,将这些values-xxxx * xxxx拷贝进去,然后让需要使用屏幕适配的module依赖这个module即可,如app module,还有一些第三方控件库module。那么就可以在你想用的地方尽情使用dimen值了。

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

推荐阅读更多精彩内容