Android屏幕适配

本文总结了Android屏幕适配的各种方法,包括图片、布局、代码等方面的适配策略。探讨了屏幕尺寸、分辨率和像素密度的关系,推荐了几种适配方案,如使用dp单位、百分比适配和今日头条的适配原理,强调了适配的重要性以确保用户一致的体验效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

现在市场上各种屏幕适配方面的文章,今天我也来总结一篇

1,Android屏幕适配?

华为官方适配方案:

华为官网刘海屏适配

好,来听我解答

由于Android系统的开放性,任何用户、开发者、OEM厂商、运营商都可以对Android进行定制,于是导致:

Android系统碎片化:小米定制的MIUI、魅族定制的flyme、华为定制的EMUI等等
当然都是基于Google原生系统定制的

Android机型屏幕尺寸碎片化:5寸、5.5寸、6寸等等
Android屏幕分辨率碎片化:320x480、480x800、720x1280、1080x1920
据友盟指数显示,统计至2015年12月,支持Android的设备共有27796种

当Android系统、屏幕尺寸、屏幕密度出现碎片化的时候,就很容易出现同一元素在不同手机上显示不同的问题。

试想一下这么一个场景:
为4.3寸屏幕准备的UI设计图,运行在5.0寸的屏幕上,很可能在右侧和下侧存在大量的空白;而5.0寸的UI设计图运行到4.3寸的设备上,很可能显示不下。

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

一部手机的分辨率是宽x高,屏幕大小是以寸为单位,那么三者的关系是:

保证用户一致体验效果

“使得某一元素在Android不同尺寸、不同分辨率的手机上具备相同的显示效果

于是,我们便需要对Android屏幕进行适配”

2,我们来说一下Android屏幕适配

1.图片适配

开发过程中切图越多越好吗? 图标的大小怎么切 72x72 ,48x48,96x96,144x144,192x192 一般切多少套图片? 如果能用一套图片解决问题,就一套就够了 能不用图片就不用图片,shap资源 drawable-ldpi drawable-mdpi drawable-hdpi drawable-xhdpi drawable-xxhdpi
当同名的一张图片mm.jpg ,但内容不同图片,分别放置不同的目录,手机会更加当前屏幕密度,加载不同的图片。

Android开发者在做图片适配时需要注意一下两点

1、盛放图片的控件要用dip单位来定义其长宽。
2、  最好在ldpi、mdpi、hdpi、xhdpi、xxhdpi文件夹下提供大小比例为3:4:6:8:12的图片。当然如果有质量好的.9.png图片的话,提供一个也可以

步骤1:根据以下尺寸范围针对各密度生成相应的图片。

比如说,如果我们为 xhdpi 设备生成了 200x200 px尺寸的图片,就应该按照相应比例地为 hdpi、mdpi 和 ldpi 设备分别生成 150x150、100x100 和 75x75 尺寸的图片

2.布局适配

RelativeLayout
布局的子控件之间使用相对位置的方式排列,因为RelativeLayout讲究的是相对位置,即使屏幕的大小改变,视图之前的相对位置都不会变化,与屏幕大小无关,灵活性很强

  • LinearLayout
    通过多层嵌套LinearLayout和组合使
    用"wrap_content"和"match_parent"已经可以构建出足够复杂的布局。但是LinearLayout无法准确地控制子视图之间的位置关系,只能简单的一个挨着一个地排列

对于屏幕适配来说,使用相对布局(RelativeLayout)将会是更好的解决方案
 

Android开发时用dp而不是px单位设置图片大小,是Android特有的单位
场景:假如同样都是画一条长度是屏幕一半的线,如果使用px作为计量单位,那么在480x800分辨率手机上设置应为240px;在320x480的手机上应设置为160px,二者设置就不同了;如果使用dp为单位,在这两种分辨率下,160dp都显示为屏幕一半的长度。
dp与px的转换
因为ui给你的设计图是以px为单位的,Android开发则是使用dp作为单位的,那么该如何转换呢?

在Android中,规定以160dpi(即屏幕分辨率为320x480)为基准:1dp=1px

3.代码适配

不详细说,因为淘汰了,  知道就行

4.权重适配

不详细说,因为淘汰了,  知道就行

5.尺寸适配

不详细说,因为淘汰了,  知道就行

6.百分比适配

Android5.0之后引入百分比适配

  1. 以某一分辨率为基准,生成所有分辨率对应像素数列表
  2. 将生成像素数列表存放在res目录下对应的values文件下
  3. 根据UI设计师给出设计图上的尺寸,找到对应像素数的单位,然后设置给控件即可

7.还有就是今日头条适配  说一下原理

今日头条屏幕适配方案的核心原理在于,根据以下公式算出 density

当前设备屏幕总宽度(单位为像素)/  设计图总宽度(单位为 dp) = density

density 的意思就是 1 dp 占当前设备多少像素

为什么要算出 density,这和屏幕适配有什么关系呢?

public static float applyDimension(int unit, float value,
                                       DisplayMetrics metrics)
    {
        switch (unit) {
        case COMPLEX_UNIT_PX:
            return value;
        case COMPLEX_UNIT_DIP:
            return value * metrics.density;
        case COMPLEX_UNIT_SP:
            return value * metrics.scaledDensity;
        case COMPLEX_UNIT_PT:
            return value * metrics.xdpi * (1.0f/72);
        case COMPLEX_UNIT_IN:
            return value * metrics.xdpi;
        case COMPLEX_UNIT_MM:
            return value * metrics.xdpi * (1.0f/25.4f);
        }
        return 0;
    }

不管你在布局文件中填写的是什么单位,最后都会被转化为 px,系统就是通过上面的方法,将你在项目中任何地方填写的单位都转换为 px 的

所以我们常用的 px 转 dp 的公式 dp = px / density,就是根据上面的方法得来的,density 在公式的运算中扮演着至关重要的一步

要看懂下面的内容,还得明白,今日头条的适配方式,今日头条适配方案默认项目中只能以高或宽中的一个作为基准,进行适配,为什么不像 AndroidAutoLayout 一样,高以高为基准,宽以宽为基准,同时进行适配呢

这就引出了一个现在比较棘手的问题,大部分市面上的 Android 设备的屏幕高宽比都不一致,特别是现在大量全面屏的问世,这个问题更加严重,不同厂商推出的全面屏手机的屏幕高宽比都可能不一致

这时我们只以高或宽其中的一个作为基准进行适配,就会有效的避免布局在高宽比不一致的屏幕上出现变形的问题

明白这个后,我再来说说 densitydensity 在每个设备上都是固定的,DPI / 160 = density屏幕的总 px 宽度 / density = 屏幕的总 dp 宽度

  • 设备 1,屏幕宽度为 1080px480DPI,屏幕总 dp 宽度为 1080 / (480 / 160) = 360dp

  • 设备 2,屏幕宽度为 1440560DPI,屏幕总 dp 宽度为 1440 / (560 / 160) = 411dp

可以看到屏幕的总 dp 宽度在不同的设备上是会变化的,但是我们在布局中填写的 dp 值却是固定不变的

这会导致什么呢?假设我们布局中有一个 View 的宽度为 100dp,在设备 1 中 该 View 的宽度占整个屏幕宽度的 27.8% (100 / 360 = 0.278)

但在设备 2 中该 View 的宽度就只能占整个屏幕宽度的 24.3% (100 / 411 = 0.243),可以看到这个 View在像素越高的屏幕上,dp 值虽然没变,但是与屏幕的实际比例却发生了较大的变化,所以肉眼的观看效果,会越来越小,这就导致了传统的填写 dp 的屏幕适配方式产生了较大的误差

这时我们要想完美适配,那就必须保证这个 View 在任何分辨率的屏幕上,与屏幕的比例都是相同的

这时我们该怎么做呢?改变每个 View 的 dp 值?不现实,在每个设备上都要通过代码动态计算 View 的 dp值,工作量太大

如果每个 View 的 dp 值是固定不变的,那我们只要保证每个设备的屏幕总 dp 宽度不变,就能保证每个View 在所有分辨率的屏幕上与屏幕的比例都保持不变,从而完成等比例适配,并且这个屏幕总 dp 宽度如果还能保证和设计图的宽度一致的话,那我们在布局时就可以直接按照设计图上的尺寸填写 dp 值

屏幕的总 px 宽度 / density = 屏幕的总 dp 宽度

在这个公式中我们要保证 屏幕的总 dp 宽度 和 设计图总宽度 一致,并且在所有分辨率的屏幕上都保持不变,我们需要怎么做呢?屏幕的总 px 宽度 每个设备都不一致,这个值是肯定会变化的,这时今日头条的公式就派上用场了

当前设备屏幕总宽度(单位为像素)/  设计图总宽度(单位为 dp) = density

这个公式就是把上面公式中的 屏幕的总 dp 宽度 换成 设计图总宽度,原理都是一样的,只要 density 根据不同的设备进行实时计算并作出改变,就能保证 设计图总宽度 不变,也就完成了适配

优点

  • 使用成本非常低,操作非常简单,使用该方案后在页面布局时不需要额外的代码和操作,这点可以说完虐其他屏幕适配方案

  • 侵入性非常低,该方案和项目完全解耦,在项目布局时不会依赖哪怕一行该方案的代码,而且使用的还是Android 官方的 API,意味着当你遇到什么问题无法解决,想切换为其他屏幕适配方案时,基本不需要更改之前的代码,整个切换过程几乎在瞬间完成,会少很多麻烦,节约很多时间,试错成本接近于 0

  • 可适配三方库的控件和系统的控件(不止是 Activity 和 FragmentDialogToast 等所有系统控件都可以适配),由于修改的 density 在整个项目中是全局的,所以只要一次修改,项目中的所有地方都会受益

  • 不会有任何性能的损耗

缺点

暂时没发现其他什么很明显的缺点,已知的缺点有一个,那就是第三个优点,它既是这个方案的优点也同样是缺点,但是就这一个缺点也是非常致命的

只需要修改一次 density,项目中的所有地方都会自动适配,这个看似解放了双手,减少了很多操作,但是实际上反应了一个缺点,那就是只能一刀切的将整个项目进行适配,但适配范围是不可控的

这样不是很好吗?这样本来是很好的,但是应用到这个方案是就不好了,因为我上面的原理也分析了,这个方案依赖于设计图尺寸,但是项目中的系统控件、三方库控件、等非我们项目自身设计的控件,它们的设计图尺寸并不会和我们项目自身的设计图尺寸一样

当这个适配方案不分类型,将所有控件都强行使用我们项目自身的设计图尺寸进行适配时,这时就会出现问题,当某个系统控件或三方库控件的设计图尺寸和和我们项目自身的设计图尺寸差距非常大时,这个问题就越严重

相信原理你们都懂了,最后推荐几种方案:

最后推荐几种方案:

 官方适配方案

dp。dp是Android开发中特有的一个单位。与px不同,dp是基于屏幕像素密度的一种单位。在�密度低的屏幕上或许1dp=1px,但在密度高的屏幕上可能1dp=4px。编写布局xml时,如果一个控件的长宽都使用dp来指定,那么能确保该控件在各种大小与分辨率的屏幕下的绝对大小都大致相当。也就是说无论在pad下还是大小屏手机下,我们实际看到的该控件的大小是差不多的:

1:方案1

编写脚本将长度转换成各分辨率下的长度,缺点是难以覆盖市面上的所有分辨率。

2:方案2

AutoLayout支持库。该库的想法非常好:对照设计图,使用px编写布局,不影响预览;绘制阶段将对应设计图的px数值计算转换为当前屏幕下适配的大小;为简化接入,inflate时自动将�各Layout转换为对应的AutoLayout,从而不需要在所有的xml中更改。但是同时该库也存在以下等问题:

3:方案3:

今日头条技术团队

                                       点开自己看吧骚年

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值