Android 屏幕适配方案解析(二)

下面列举常用的适配方案:

  • dp适配方案
  • 宽高限定符适配方案
  • AndroidAutoLayout适配方案
  • sw限定符适配方案
  • 今日头条适配方案
  • AndroidAutoSize适配方案

1、dp适配方案

众所周知,在开发过程中标识尺寸的时候,Android并不推荐使用px这个真实像素单位,因为相同尺寸在不同分辨率的手机显示效果各不相同,如下为图片宽高为250x250(px),在分辨率:480x800、720x1280、1080x1920的显示效果图:
image.png

出现类似于上图这样的效果,整体的布局效果可能会变形,所以px这个单位在布局文件中是不推荐的。

相对应的Android推荐使用dp作为尺寸单位来适配UI,之前我们讲过,dp为密度无关像素,与终端上的实际物理像素点无关,可以保证在不同屏幕像素密度的设备上显示相同的效果。

下面还是根据实例来说明一下,如下为图片宽高为250x250(dp),在分辨率:480x800、720x1280、1080x1920的显示效果图:

image.png

从效果图可以看出,宽高250dp在不同分辨率手机整体的布局效果差异并不大,为啥会这样呢?

我们知道同样尺寸在不同分辨率的设备,每1dp所代表的像素数量是不一样的,如表格所示:

image.png

由表格可以看出,在480x800、720x1280、1080x1920的手机,dpi是不同的,这也是说,1dp在这些不同分辨率的手机中,分别对应的1.5px、2px、3px,这样当我们用dp作为控件大小单位的时候,在不同分辨率的手机上看到的大小一样,此时各手机上显示的比例也就一致啦。

以上的适配方式,通过dp再加上自适应布局和weight比例布局可以基本解决不同手机上适配的问题,这基本上就是最原始的Android适配方案。

那这种方案有没缺点呢?
自然是有的,不然也不会推出这么多的适配方案,那我们来看看有啥缺点。
我们知道Android之所以碎片化这么严重,跟Android系统、屏幕尺寸、屏幕密度的碎片化有很大的关系,而手机厂商生产的手机设备也并没有按照屏幕尺寸、分辨率和像素密度的关系规则来实现,比如屏幕分辨率1080x1920,屏幕尺寸为5,那么dip为440,假如UI设计图按屏幕宽度为375dp设计,那么这样会存在啥问题呢?

根据上述描述,我们可以通过计算出屏幕宽度为:1080/(440/160) = 393dp,也就是说实际的屏幕宽度是比设计图的要宽的,那这样即使用dp为单位也无法跟其它设备显示同样的效果,这就需要通过估算或者设定规范值等等进行换算设置,这也就需要我们耗费精力去转换尺寸,这会极大降低开发效率。

2、宽高限定符适配方案

所谓的宽高限定符适配就是穷举市面上所有的Android手机的宽高像素值,不过需要先设定一个基准,然后其它分辨率根据这个基准做适配,如图所示:

image.png

那什么叫设定一个基准呢?
比如设定320x480的分辨率为基准,那么:

基准宽度为320,即将任何分辨率的宽度分为320份,取值为x1到x320。

基准长度为480,即将任何分辨率的长度分为480份,取值为y1到y480。

那么该基准尺寸编写对应的dimens文件为:


image.png

那什么又叫其它分辨率根据这个基准做适配呢?
比如拿480x800分辨率的手机来说,需要在项目中values-800x480目录下的dimens.xml文件中的如下设置,如图所示:

image.png

那么这份数据是怎么计算得到的呢,那当然是在基准分辨率的基础上计算得到的,以下为宽度x演示即:

x1=(480/基准)1=(480/320)1=1.5px

x2=(480/基准)2=(480/320)2=3px

x320=(480/基准)320=(480/320)320=480px

同理长度y计算也是一样的。

这个时候有童鞋又说了,市面上我怎么知道有多少分辨率的手机啊,就算知道所有分辨率,每个这么计算不得写废了啊,淡定哈,这些都是可以通过工具自动生成,这得感谢鸿洋大佬提供的生成工具。

1、分析需要的支持的分辨率

对于主流的分辨率已经集成到程序里了,对于比较特殊的可以通过参数指定,而关于屏幕分辨率信息,可以通过该网站查询:点击这里跳转

2、自动生成文件的程序地址

点击这里跳转获取自动生成程序

image.png

这里提供了个jar包,默认情况下,双击即可生成,如图所示:
image.png

这里默认内置了常用的分辨率,默认基准为480*320,对于特殊需求,可以通过命令行指定即可,比如我想以分辨率1280 * 800为基准 ,并且额外支持尺寸:1152 * 735;4500 * 3200,如图所示:


image.png

格式如下:

java -jar xx.jar width height width,height_width,height

最后自动生成文件如图所示:


image.png

这样就更改了默认的基准,还添加了额外支持的分辨率。

使用这种适配方案,可以按照UI设计稿的尺寸为基准分辨率,这时运行在不同分辨率的手机中,这些系统会根据这些dimens引用去该分辨率的文件夹下面寻找对应的值,这样基本解决了我们的适配问题,而且极大的提升了我们UI开发的效率。

那这种方案有没缺点呢?当然也是有的

  • 最明显的肯定就是占用资源大,会增加APK的体积
  • 容错机制大,需要精准命中资源文件才能适配,比如1920x1080的手机就一定要找到1920x1080的限定符,否则就只能用统一的默认的dimens文件了。而使用默认的尺寸的话,UI就很可能变形。

3、AndroidAutoLayout适配方案

所谓的AndroidAutoLayout适配方案,其实就是UI适配框架,这个是鸿洋大佬写的适配方案,这也是受宽高限定符适配方案启发写的,使用方式也比较简单,直接填写设计图上的像素尺寸即可完成适配,不过目前这个框架已停止维护。
下面还是根据实例来讲解集成过程:

1、引入该适配框架
implementation 'com.zhy:autolayout:1.4.5'
2、在项目中的AndroidManifest配置文件注明设计稿的尺寸,这里测试以720x1280为例:
       <!-- 测试手机的尺寸 -->
       <meta-data
           android:name="design_width"
           android:value="720" />

       <meta-data
           android:name="design_height"
           android:value="1280" />

3、将需要适配的Activity继承自AutoLayoutActivity,如果你不希望继承AutoLayoutActivity,可以在编写布局文件时,将:
  • LinearLayout -> AutoLinearLayout
  • RelativeLayout -> AutoRelativeLayout
  • FrameLayout -> AutoFrameLayout

这样也可以完成适配,我这里测试实例使用AutoRelativeLayout进行测试,测试布局如下:

<?xml version="1.0" encoding="utf-8"?>
<com.zhy.autolayout.AutoRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

   <ImageView
       android:layout_width="250px"
       android:layout_height="250px"
       android:layout_centerInParent="true"
       android:src="@mipmap/ic_launcher" />

</com.zhy.autolayout.AutoRelativeLayout>

测试布局文件非常的简单,只设置了图片,细心的童鞋也发现了,这里图片的宽高都是设置以px为单位,而不是我们常用的dp为单位,如图所示:
image.png

是的,你没有看错,这里可以直接在布局文件里面使用具体的像素值,例如设计稿上标注的图片是250*250,那么我们可以直接写250px,运行时框架会帮助我们根据不同手机的具体尺寸按比例伸缩,我们来看看这个实例在不同手机的测试对比效果图:


image.png

我们再来看一下没有使用AndroidAutoLayout适配方案之前不同手机的测试对比效果:


image.png

根据适配前后的对比效果还是挺明显的,我这里主要介绍的是基本的适配方案,如果你想了解更详细的适配方式,可以到这里点击这里

毫无疑问,这个UI框架是个极好的适配方案,使用简单,所要做的就是抄抄设计稿上面的px,直接写入布局文件即可完成适配,而且在宽高限定符适配方案的基础上更近一步,完美解决了容错机制的问题,让开发更加的高效。

那这个方案有没缺点呢?
当然也是有的,首先是这个UI适配框架已经停止适配,这也意味着一旦这个框架在使用过程中遇到难以解决的问题,替换起来会非常的麻烦且耗精力,当然如果你已经熟悉了这套源码除外哈。

4、sw限定符适配方案

sw限定符适配即smallestWidth适配,也叫最小宽度限定符适配,指的是Android会识别到屏幕可用高度或宽度的最小尺寸的dp值,对于手机来说,这个值其实就是手机的宽度值,而对于平板来说,这个值就是平板的高度值。然后根据识别到的结果去资源文件中寻找对应限定符文件夹下的资源文件。其实这种适配方案跟之前介绍的宽高限定符适配方案原理是一样一样的,都是系统通过特定的规则来找到对应的资源文件。

我们先来看一下资源文件,这份是通过插件生成的以375dp为基准的资源文件,插件的使用后面会介绍,如图所示:


image.png

举例说明:比如我有台测试机为小米,手机分辨率为1080x1920,屏幕像素密度为480,根据最小宽度限定符适配方案,该手机最小宽度为1080px,再根据px=dp(dpi/160),横向的dp值是1080/(480/160),也就是360dp,根据这个结果系统就会去资源文件中寻找values-sw360dp文件夹下的资源文件,如图所示:


image.png

前面说了,该方案的原理跟宽高限定符适配方案是一样的,所以也需要提前设置基准尺寸,比如我这里以375dp为基准,即将任何分辨率的宽度分为375份,我们来看看基准资源文件,如图所示:
image.png

我们再拿上面小米手机举例说明,我们来看看values-sw360dp文件夹下的资源文件,如图所示:


image.png

那么这份数据是怎么计算得到的呢,当然也是在基准尺寸的基础上计算得到的,即:
dp_1=(360/基准)1=(360/375)1=0.96dp

dp_2=(360/基准)2=(360/375)2=1.92dp

dp_375=(360/基准)375=(360/375)375=360dp

其它手机尺寸也是同理这样计算得到的。

那下面来看看资源文件是怎么生成的?

实现步骤:

1、在Android studio中安装ScreenMatch插件

点击菜单栏上的 File -> Settings -> Plugins ,搜索ScreenMatch关键字,安装插件,安装成功后,点击 “OK”,重启 Andorid Studio 即可,如图所示:


image.png
2、在项目values文件夹下需要一份dimens.xml文件,即前面说的默认基准尺寸文件,如图所示:
image.png
3、插件安装后,在项目的任意目录或文件上右键,选择 ScreenMatch 选项,如图所示:
image.png
4、然后选择需要适配的module ,我这里测试只有一个,如图所示:
image.png
5、点击 OK后 ,出现如下弹窗即表示生成资源文件成功,如图所示:
image.png

通过以上的步骤res 目录下就生成了默认尺寸的所有资源文件啦。

上面步骤是以最小宽度基准值为375dp,适配的设备最小宽度为:240,320,384,392,400,410,411,480,533,592,600,640,662,720,768,800,811,820,960,961,1024,1280,1365生成的文件,当然实际开发需要根据设计图需求进行设置,这个时候就需要更改基准值及需要适配的适配啦,那下面看看怎么更改的。
例如现在UI的设计图最小宽度为360dp,则需要更改最小宽度基准值为 360dp。假如我们需要适配的设备最小宽度保留 320,360,384,392,400,410,411,480即可,如果还需要添加其他最小宽度的设备自行加上即可,首先我们需要找到插件的screenMatch.properties配置文件并打开,如图所示:


image.png

然后我们需要在配置文件修改,修改下图中 1、3、4处的值即可,如图所示:


image.png

值得注意的是上图设置的值单位都为dp。

我们再来看看1、2、3、4表示什么意思:
1、表示最小宽度基准值,填写设计图的最小宽度值即可。
2、表示插件默认适配的最小宽度值,即默认情况下会生成如下值的 dimens.xml 文件。
3、表示需要适配的最小宽度值,即你想生成哪些 dimens.xml 文件。
4、忽略不需要适配的最小宽度值,即忽略掉插件默认生成的 dimens.xml 文件。

修改完配置文件后,重新执行步骤3就会生成新的资源文件。

我们再来看一下sw限定符适配方案的优点:
sw限定符适配方案和宽高限定符适配方案最大的区别在于:前者有很好的容错机制,如果没有value-sw360dp文件夹,系统会向下寻找,比如离360dp最近的只有value-sw350dp,那么Android就会选择value-sw350dp文件夹下面的资源文件。这个特性就完美的解决了宽高限定符适配方案的容错问题。而且sw限定符适配方案非常稳定,极低概率出现意外。在插件的配合下,学习成本也比较低。

那这种方案有没缺点:

  • 最明显的肯定也是占用资源大,会增加APK的体积
  • 在布局中引用dimens的方式,在维护过程中修改会比较麻烦。
  • 侵入性高,比如想切换其它适配方案,由于每个layout文件中有大量的dimens引用,修改起来工作量会非常巨大,切换成本非常高。

今日头条适配方案

今日头条适配方案原理在于通过公式density = 设备真实宽度(单位px)/设计图总宽度(单位dp),在确保设计图总宽度(单位dp)一定时,通过修改density值,确保所有不同尺寸分辨率设备计算出的真实宽度值正好是屏幕宽度,这样就能达到适配所有设备的目的啦。

举个例子:比如UI设计稿总宽度为360dp,这里有两台不同尺寸分辨率的设备:
设备1:分辨率1080x1920,dpi为480,正常情况下计算density=dpi/160=480/160=3,此时屏幕总宽度dp=px/density=1080/3=360;

设备2:分辨率1440x2560,dpi为560,正常情况下计算desity=dpi/160=560/160=3.5,此时屏幕总宽度dp=px/density=1440/3.5=411;

正常情况下density 在每个设备上都是固定的,那要是我们想确保设计稿总宽度360不变,再来看看density值:
设备1:分辨率1080x1920,dpi为480,计算density = 设备真实宽度(单位px)/设计图总宽度(单位dp) = 1080/360 = 3,此时屏幕总宽度dp=px/density=1080/3=360;

设备2:分辨率1440x2560,dpi为560,计算density = 设备真实宽度(单位px)/设计图总宽度(单位dp) = 1440/360 = 4,此时屏幕总宽度dp=px/density=1440/4=360;

通过对比可以看出,修改density值,确实是能确保不同分辨率设备总宽度值始终是360dp,这样就能保证UI在不同的设备上显示效果是一致的。

今日头条适配方案推导过程
通过上面例子我们知道需要修改density值,那下面我们就来看看怎么修改系统的density值:
首先我们得知道无论在布局文件中填写的是什么样单位的值,比如10dp、10sp、10px等等,最后都会被系统转换成px,这个时候有童鞋就问了,你怎么知道啊?当然是通过布局文件中dp转换源码知道的啦。

通过源码可以知道,dp转换最终都是调用系统工具类Typedvalue类中的applyDimension方法进行转换的:

     /**
    * @param unit 要转换的单位
    * @param value 单位对应的值
    * @param metrics 显示指标
    */
   public static float applyDimension(int unit, float value,DisplayMetrics metrics){
       switch (unit) {
       case COMPLEX_UNIT_PX://单位为px
           return value;
       case COMPLEX_UNIT_DIP://单位为dp
           return value * metrics.density;
       case COMPLEX_UNIT_SP://单位为sp
           return value * metrics.scaledDensity;
       case COMPLEX_UNIT_PT://单位为pt
           return value * metrics.xdpi * (1.0f/72);
       case COMPLEX_UNIT_IN://单位为in
           return value * metrics.xdpi;
       case COMPLEX_UNIT_MM://单位为mm
           return value * metrics.xdpi * (1.0f/25.4f);
       }
       return 0;
   }

系统就是通过上面的方法,将你在项目中任何地方填写的单位都转换为px,在applyDimension方法中有个参数DisplayMetrics,我们来看看这个参数的含义:

@param metrics Current display metrics to use in the conversion -- supplies display density and scaling information.

这句话的意思是转换中使用的当前显示指标,提供显示密度和缩放信息。通过applyDimension方法中dp转换:

public static float applyDimension(int unit, float value,DisplayMetrics metrics){
       switch (unit) {
       ......
       case COMPLEX_UNIT_DIP://单位为dp
           return value * metrics.density;
       ......
   }

可以发现有我们需要的density值,通过Ctrl键追踪位置发现这个值是系统工具类DisplayMetrics类的成员变量,如图所示:


image.png

而DisplayMetrics实例可以通过系统资源文件Resources类中的getDisplayMetrics方法获得,系统资源文件Resouces也可以通过Activity或者Application的Context获得:

DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();

然后就可以通过DisplayMetrics实例,修改density值啦,这里需要注意有个scaledDensity变量的影响,这个变量是字体的缩放因子,正常情况下和density相等,但是调节系统字体大小后会改变这个值,防止用户调节了系统字体。

今日头条适配的最终方案:
这里是以设计图总宽度360dp来适配,接下来只需要把我们计算好的 density 在系统中修改下即可,代码实现如下:

   /**
    * 今日头条适配方案
    *
    * @param activity
    * @param application
    */
   public static void setCustomDensity(Activity activity, final Application application) {
       //通过资源文件getResources类获取DisplayMetrics
       DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
       if (sNoncompatDensity == 0) {
           //保存之前density值
           sNoncompatDensity = appDisplayMetrics.density;
           //保存之前scaledDensity值,scaledDensity为字体的缩放因子,正常情况下和density相等,但是调节系统字体大小后会改变这个值
           sNoncompatScaledDensity = appDisplayMetrics.scaledDensity;
           //监听设备系统字体切换
           application.registerComponentCallbacks(new ComponentCallbacks() {

               public void onConfigurationChanged(Configuration newConfig) {
                   if (newConfig != null && newConfig.fontScale > 0) {
                       //调节系统字体大小后改变的值
                       sNoncompatScaledDensity = application.getResources().getDisplayMetrics().scaledDensity;
                   }
               }

               public void onLowMemory() {

               }
           });
       }

       //获取以设计图总宽度360dp下的density值
       float targetDensity = appDisplayMetrics.widthPixels / 360;
       //通过计算之前scaledDensity和density的比获得scaledDensity值
       float targetScaleDensity = targetDensity * (sNoncompatScaledDensity / sNoncompatDensity);
       //获取以设计图总宽度360dp下的dpi值
       int targetDensityDpi = (int) (160 * targetDensity);
       //设置系统density值
       appDisplayMetrics.density = targetDensity;
       //设置系统scaledDensity值
       appDisplayMetrics.scaledDensity = targetScaleDensity;
       //设置系统densityDpi值
       appDisplayMetrics.densityDpi = targetDensityDpi;

       //获取当前activity的DisplayMetrics
       final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
       //设置当前activity的density值
       activityDisplayMetrics.density = targetDensity;
       //设置当前activity的scaledDensity值
       activityDisplayMetrics.scaledDensity = targetScaleDensity;
       //设置当前activity的densityDpi值
       activityDisplayMetrics.densityDpi = targetDensityDpi;
   }

上面代码是今日头条的最终方案,为了方便阅读,我只是基于个人理解做了标注解析,不对的地方请大佬们指正。

今日头条适配步骤:
下面来看验证一下这种适配方案的可行性。

1、布局文件,这里沿用之前的布局,只有一张宽高为150x150(dp)的图片,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

   <ImageView
       android:layout_width="150dp"
       android:layout_height="150dp"
       android:layout_centerInParent="true"
       android:src="@mipmap/ic_launcher" />

</RelativeLayout> 
2、这里将今日头条适配方案封装成了工具类,如下所示:
public class CustomDensityUtil {
   private static float sNoncompatDensity;
   private static float sNoncompatScaledDensity;

   /**
    * 今日头条适配方案
    *
    * @param activity
    * @param application
    */
   public static void setCustomDensity(Activity activity, final Application application) {
       //通过资源文件getResources类获取DisplayMetrics
       DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
       if (sNoncompatDensity == 0) {
           //保存之前density值
           sNoncompatDensity = appDisplayMetrics.density;
           //保存之前scaledDensity值,scaledDensity为字体的缩放因子,正常情况下和density相等,但是调节系统字体大小后会改变这个值
           sNoncompatScaledDensity = appDisplayMetrics.scaledDensity;
           //监听设备系统字体切换
           application.registerComponentCallbacks(new ComponentCallbacks() {

               public void onConfigurationChanged(Configuration newConfig) {
                   if (newConfig != null && newConfig.fontScale > 0) {
                       //调节系统字体大小后改变的值
                       sNoncompatScaledDensity = application.getResources().getDisplayMetrics().scaledDensity;
                   }
               }

               public void onLowMemory() {

               }
           });
       }

       //获取以设计图总宽度360dp下的density值
       float targetDensity = appDisplayMetrics.widthPixels / 360;
       //通过计算之前scaledDensity和density的比获得scaledDensity值
       float targetScaleDensity = targetDensity * (sNoncompatScaledDensity / sNoncompatDensity);
       //获取以设计图总宽度360dp下的dpi值
       int targetDensityDpi = (int) (160 * targetDensity);
       //设置系统density值
       appDisplayMetrics.density = targetDensity;
       //设置系统scaledDensity值
       appDisplayMetrics.scaledDensity = targetScaleDensity;
       //设置系统densityDpi值
       appDisplayMetrics.densityDpi = targetDensityDpi;

       //获取当前activity的DisplayMetrics
       final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
       //设置当前activity的density值
       activityDisplayMetrics.density = targetDensity;
       //设置当前activity的scaledDensity值
       activityDisplayMetrics.scaledDensity = targetScaleDensity;
       //设置当前activity的densityDpi值
       activityDisplayMetrics.densityDpi = targetDensityDpi;
   }
}
3、在Activity中的onCreate方法中调用,如下所示:
CustomDensityUtil.setCustomDensity(MainActivity.this, getApplication());

到这里就完成了,是不是挺简单的呢,下面来看看在分辨率:480x800、720x1280、1080x1920的测试显示效果图:


image.png

再来看一下没有使用今日头条适配方案之前不同手机的测试对比效果:


image.png

根据适配前后的对比效果还是挺明显的。

今日头条适配方案优点

  • 1、侵入性很低,而且没有涉及私有API,该方案与项目完全解耦,今日头条大厂在使用,稳定性有保证。
  • 2、使用成本非常低,操作简单方便。
  • 3、接入没有任何的性能损耗,使用的都是系统API。

今日头条适配方案缺点

  • 1、只需要修改一次 density,项目中的所有地方都会自动适配,这个看似解放了双手,减少了很多操作,但是实际上反映了一个缺点,那就是只能一刀切的将整个项目进行适配,但适配范围是不可控的。比如项目中使用了第三方库控件等不是我们项目自身设计的控件,这时就会出现和我们项目自身的设计图尺寸差距非常大的问题。
  • 2、使用过程中需要进行registerComponentCallbacks监听内容文字的大小改变情况,解决退出应用修改文字大小后,会出现文字大小不改变的情况。

AndroidAutoSize适配方案

所谓的AndroidAutoSize适配方案其实就是今日头条适配方案的升级版,是基于今日头条适配方案进行拓展的开源库,该库在很大程度上解决了今日头条适配方案的缺点,使用方式也比较简单,只需要填写设计图尺寸这一步即可接入项目,还支持对Activity、Fragment进行取消适配,灵活性会更强。
下面还是根据实例来讲解集成过程:

1、根目录build.gradle添加:
allprojects {
   repositories {
       ...
       maven { url "https://jitpack.io" }
   }
}
2、添加该适配框架依赖
implementation 'com.github.JessYanCoding:AndroidAutoSize:v1.2.1'
3、在项目中的AndroidManifest配置文件注明设计稿的尺寸,这里测试以360x640为例:
<manifest>
   <application>            
       <meta-data
           android:name="design_width_in_dp"
           android:value="360"/>
       <meta-data
           android:name="design_height_in_dp"
           android:value="640"/>           
    </application>           
</manifest>

如果只是想使用AndroidAutoSize适配方案的基础功能,AndroidAutoSize框架的使用方法在这里就结束了,只需要上面这一步,即可帮助你以最简单的方式接入AndroidAutoSize适配框架,我这里只做适配方案有效性演示,需要拓展需求的请参考下面Github地址有详细介绍。

4、测试布局文件非常的简单,只设置了图片,为了突出跟今日头条适配方案测试结果不同,这里设置图片宽高为120x120(dp),测试布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

   <ImageView
       android:layout_width="120dp"
       android:layout_height="120dp"
       android:layout_centerInParent="true"
       android:src="@mipmap/ic_launcher" />

</RelativeLayout>

我们来看看这个实例在不同手机的测试对比效果图:


image.png

再来看一下没有使用AndroidAutoSize适配方案之前不同手机的测试对比效果:


image.png

根据适配前后的对比效果还是挺明显的,AndroidAutoSize适配方案是根据今日头条屏幕适配方案官方公布的 30 行不到的代码,经过不断的优化和扩展,发展成了现在拥有将近20个类文件,上千行代码的全面性屏幕适配框架,在迭代的过程中完善和优化了很多功能,相比今日头条屏幕适配方案官方公布的原始代码,AndroidAutoSize适配方案更加稳定、更加易用、更加强大,感兴趣的可以去阅读源码,注释非常详细,这里就不做过多的介绍啦,点击进入源码地址

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

推荐阅读更多精彩内容