Android 屏幕适配方案

前言

由于我之前是在一些设备原厂工作的只需要负责sdk的工作以及去给客户驻点开发的,基本不会涉及到屏幕适配,就算是客户那边也是固定的一个Android设备不需要适配;随着我离职之后去面试别的公司,人家一问到我屏幕适配时候我回答不出来,故此我花了些时间研究网上所说的屏幕适配,然后我总结借鉴了一下。

屏幕分辨率限定符与 smallestWidth 限定符适配原理

屏幕分辨率限定符适配原理

屏幕分辨率限定符适配需要在 res 文件夹下创建各种屏幕分辨率对应的 values-xxx 文件夹,如下图:


这样设计图里面显示多少px就可以这么写@dimen/x720或者@dimen/y720,相应的屏幕配比会自动加载相应配比的资源文件,

UI设计的尺寸是多少那就按照那个比例为基准生成对应的资源,比如UI给的是720*1280的(这个单位是px,dpi=160) 然后我就会以那个为基准生成一套资源文件


代码在MakeXml,然后UI设计上标志是多少px,在资源引用时候就使用多少px


缺点:这个方案缺点很明显,只适用常规的手机屏幕尺寸。

这个方案的还有鸿洋老铁的https://blog.csdn.net/lmj623565791/article/details/45460089

效果图:


320*480


576*1027


720*1280

smallestWidth 限定符 适配原理

smallestWidth 限定符适配原理与屏幕分辨率限定符适配原理一样,系统都是根据限定符去寻找对应的 dimens.xml 文件。例如程序运行在最小宽度为 360dp 的设备上,系统会自动找到对应的 values-sw360dp 文件夹下的 dimens.xml 文件。区别就在于屏幕分辨率限定符适配是拿 px 值等比例缩放,而 smallestWidth 限定符适配是拿 dp 值来等比缩放而已。需要注意的是“最小宽度”是不区分方向的,即无论是宽度还是高度,哪一边小就认为哪一边是“最小宽度”。如下分别为最小宽度为 360dp 与最小宽度为 640dp 所对应的 dimens.xml 文件:


获取设备最小宽度代码为:

DisplayMetrics dm = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(dm);

int heightPixels = ScreenUtils.getScreenHeight(this);

int widthPixels = ScreenUtils.getScreenWidth(this);

float density = dm.density; float heightDP = heightPixels / density;

float widthDP = widthPixels / density;

float smallestWidthDP;

if(widthDP < heightDP) {

    smallestWidthDP = widthDP;

}else {

    smallestWidthDP = heightDP;

}

ScreenUtils——>ScreenUtils

使用步骤

1、以设计图最小宽度(单位为 dp)作为基准值,生成所有设备对应的 dimens.xml 文件

    这个可以使用工具ScreenMatch工具,具体怎么使用我这里就不解释了,网上很多资料

2、根据设计图标注,在布局写上对应的值。

设计图标注多少 dp,布局中就写多少 dp ,非常方便!

如果需要动态设置尺寸

/*获取sp值*/

float pxValue = getResources().getDimension(R.dimen.sp_15);//获取对应资源文件下的sp值

int spValue = ConvertUtils.px2sp(this, pxValue);//将px值转换成sp值

mTvShowParams.setTextSize(spValue);//设置文字大小 /*获取dp值*/

float pxValue2 = getResources().getDimension(R.dimen.dp_360);//获取对应资源文件下的dp值

int dpValue = ConvertUtils.px2dp(this, pxValue2);//将px值转换成dp值

使用步骤总结

说了这么多,其实只需要简单的 2 步:

以设计图最小宽度(单位为 dp)作为基准值,利用插件生成所有设备对应的 dimens.xml 文件

根据设计图标注,标注多少 dp,布局中就写多少dp,格式为@dimen/dp_XX。(注意:UI给到的图如果是px单位的话你就得换算成dp单位的,例如:UI给的是1920*1080 单位是px然后你问清楚这个是对应320dp*480dp的屏幕还是哪一款,最后是根据那个dp来标注的,个人理解,比如我那个“益糯健康这个控件距离顶部是126px,但是以dp标记缺失63dp”

缺点:宽度可以适配了但是高度没办法,


距离底部变长了

ConstraintLayout新布局 具体鸿洋老铁

鸿洋 AutoLayout全新的适配方式 堪称适配终结者

AutoLayout我就不介绍了  原文肯定讲的更好听

今日头条适配方案

因为Android中的dp在渲染前会将dp转换成px,计算公式:

px = density * dp;

density = dpi/160;

px = dp * (dpi/160);

屏幕尺寸、分辨率】像素密度三者关系


举个例子:屏幕分辨率为:1920*1080,屏幕尺寸为5吋的话,那么dpi为440。

这样会遇到一些问题:假设我们UI设计图是按屏幕宽度为360dp来设计的,那么在上述设备上,屏幕宽度其实为1080/(440/160)=392.7dp,也就是屏幕是比设计图要宽的。这种情况下, 即使使用dp也是无法在不同设备上显示为同样效果的。 同时还存在部分设备屏幕宽度不足360dp,这时就会导致按360dp宽度来开发实际显示不全的情况。

而且上述屏幕尺寸、分辨率和像素密度的关系,很多设备并没有按此规则来实现, 因此dpi的值非常乱,没有规律可循,从而导致使用dp适配效果差强人意。

所以我们得从dp和px的转换公式 :px = dp * density 入手

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

通过阅读源码,我们可以得知,density 是 DisplayMetrics 中的成员变量,而 DisplayMetrics 实例通过Resources#getDisplayMetrics可以获得,而Resouces通过Activity或者Application的Context获得。

先来熟悉下 DisplayMetrics 中和适配相关的几个变量:

DisplayMetrics#density 就是上述的density

DisplayMetrics#densityDpi 就是上述的dpi

DisplayMetrics#scaledDensity字体的缩放因子,正常情况下和density相等,但是调节系统字体大小后会改变这个值

所以我们完全可以修改DisplayMetrics的相关数据来解决问题,

具体使用看UI给的是尺寸  我这边的例子是1280*800然后dpi为160的

剩下的就是根据设计图上面的标注的距离和字体直接填写就好了,

不过注意调用前是在setContentView()前调用

Density.setDensity(this);

Density.setDefault(this);

具体代码demo

具体我借鉴的原文在这  ——字节跳动

其实适配还有很多,这些只是我使用过的,具体呢都是使用步骤,你们要是想了解更实际的得自己深究了

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

推荐阅读更多精彩内容

  • 前言 本篇只介绍最主流的两种屏幕适配方案。 AndroidAutosize 几个基础概念:dp :就...
    杨华_6f65阅读 480评论 0 1
  • 前言 本文为自身的总结与结合其他文章引用而成,分别为: wangwangli6:Android开发:最全面、最易懂...
    ghroost阅读 7,135评论 0 6
  • 目录介绍 1.屏幕适配定义 2.相关重要的概念2.1 屏幕尺寸[物理尺寸]2.2 屏幕分辨率[px]2.3 屏幕像...
    杨充211阅读 1,532评论 0 1
  • 更新:由于该适配方案越来越多人使用,也有很多人遇到不太理解的问题。所以为了大家更好的使用,我将文章很多内容更新了,...
    wildma阅读 230,106评论 355 1,136
  • 感谢这些日子以来喜欢我关注我写作的人,我相信阅读文字这种沟通方式,是比面对面的交流更深情也更能触碰到内心深处...
    Apple树阅读 289评论 0 0