浅谈Android的适配

来源:互联网 发布:linux vim配置命令 编辑:程序博客网 时间:2024/06/07 02:17

众所周知,开源的安卓,无数的机型,苦了我们程序狗。特别在屏幕适配方面,在工作当中,做适配是整个项目很重要的一部分,狠心的测试会为了1Px的差距,跟你墨迹半天(说的有点夸张,测试妹子还是很多的)。
本文将从以下几点来做适配:

  • px与dp
  • 权重适配
  • 从布局上考虑(layout res)
  • 资源文件(drawable res)
  • 尺寸(dimens)
  • 9patch图
  • 动态的添加代码
  • 系统字体大小

px与dp

px:简单来说,是一个固定值。我们在布局中设置宽高时使用px,那么在各个手机设备上显示的是一个固定值,那么显然是不适合我们使用的。dp:与px不同的时,在布局中设置宽高使用dp,在各个不同的尺寸的手机上回根据手机本身的像素密度来调整设置的尺寸。原因可查阅 ([dp])(http://stackoverflow.com/questions/2025282/difference-between-px-dp-dip-and-sp-in-android).
所以我们在布局中使用dp,不要使用px(当然在游戏的制作过程中可不是这样)

权重适配

在手机适配中,使用最多也是权重适配,但是权重也不能滥用。权重虽好,适可而止。通过weight属性可以很好的按比例进行分配手机的空间,并且在各种手机上都适用。但是也有很大的弊端,如果大量的使用权重,在复杂的布局文件中。计算比例会很麻烦,也不利于阅读。其实,这不是重点,因为我们计算麻烦,但效果很好(只要会小学数学就可以了)。重点的是我们过度的使用权重会造成我们的性能差,渲染慢,影响用户体验,这当然对我们优秀的程序员是不可以容忍的。
原因是在加载布局时:手机是拿到屏幕的宽度和高度,在测量布局的宽度和高度。使用权重时,系统要根据权重来计算出宽高尺寸,导致渲染速度慢,这对性能有一定的影响,会产生一定时间的延时,影响用户体验(用户是我们的衣食父母,没办法)。在github上有好几个关于适配的开源项目,建议大家可以看看。
https://github.com/hongyangAndroid/android-percent-support-extend
https://github.com/devsoulwolf/Android-RatioLayout

layout(res)

布局适配,这是很有效的方法,可以达到完美适配。在各种条件允许的条件下,我们可以使用这种适配方式,就是对相应的手机尺寸,我们做相应的布局。这想想都可怕,不过在实际工作中,几乎不会使用这种方式来做适配的,因为这样很耗财力物力各种力。
在 res目录下添加例如layout-320x240, layout-480x320 这样的文件夹,在这下写相应的布局的。这是最完美的解决适配的办法,可是也是最不可行的办法(万恶的资本主义)。我们在工作中,基本都是一套布局闯天下的,除非遇到像魅族这样的变态,我们才有可能(只是有可能)为魅族弄一套布局,毕竟魅族的用户不可忽视。

资源文件(drawable res)

资源文件适配和layout相似,可以进行切多套图片来分别放在对应的drawable中(hdpi,mdpi,xhdpi,xxhdpi…)。放在不同的目录下,系统会自动的寻找与手机相近的尺寸的图片。同理这样也是最完美的解决办法,也是最行不通的解决办法。万恶的资本主义,丧失了我们追求完美的权利。在工作中,一般根据公司的要求来切几套图(我们公司都是三套图),这个得跟公司决定适应哪些手机来决定。
还有在切图的过程中,我们的UI美女可能是以ios的模板来给我们来弄的,这时我们要多沟通,共同特别的重要。如果时间赶的话,我们可以让UI美女只做ios端的切图,我们可以用iPhone5的切图。因为ios的尺寸是640*960,android当密度等于120即(320*480)时,1PX=1DP,所以android和ios的标注像素之间的换算关:即ios像素尺寸*1/2=android dp尺寸;当然这也是没办法的办法。
关于切图:
第一,长宽最好是3的倍数(根据android的推荐logo图标的大小是48(mdpi),72(hdpi),96(xhdpi)得出的最小公约数)。
  第二,长宽最好是偶数。因为奇数在进行等比压缩的时候可能有问题。
  第三,根据上面两条,如果长宽是6的倍数最理想。

尺寸(dimens)

不同像素密度手机加载不同values文件夹下的dimens.xml文件,例如:
value-1280x720、value-800x480下的dimens.xml文件中设置不同dp值。

value-800x480:dp和px的转换关系1dp = 1.5px

<resources>    <dimen name="width">160dp</dimen></resources>

value-1280x720:dp和px的转换关系1dp = 2px

<resources>    <dimen name="width">180dp</dimen></resources>

9patch图

*.9.PNG 是标准的png格式,可以通过使用9patch图来做适配,可以拉伸和缩放。可以是文字的大小不变,png图会自动适应文字。这非常的有用,制作9patch图可以使用android自带的工具。

动态的添加代码

在xml文件中设置非常的简单,但是不便于我们的管理。我们可以采用动态的添加代码,我们便于控制,但是这样又不符合我们的原则(降低耦合度)。
首先我们得获取屏幕的宽高:

    // 第一种:        WindowManager manager = getWindowManager();        int width = manager.getDefaultDisplay().getWidth();        int height = manager.getDefaultDisplay().getHeight();    // 第二种:    DisplayMetrics dMetrics = new DisplayMetrics();    getWindowManager().getDefaultDisplay().getMetrics(dMetrics);    int screenWidth = dMetrics.widthPixels;    int screenHeight = dMetrics.heightPixels;    //通过DisplayMetrics获取屏幕的各项参数      dm.widthPixels;     //屏幕的宽度(像素)      dm.heightPixels;    //屏幕的高度(像素)      dm.densityDpi;      //屏幕的像素密度 

用于进行屏幕适配的工具类:

public class DisplayUtil {      //以下三个常量为基准参数,取决于开发界面时所使用的设备的屏幕参数,其余的设备都基于此参数进行适配      public static final double BASE_WIDTH = 1280;       //屏幕的宽度      public static final double BASE_HEIGHT = 720;       //屏幕的高度      public static final double BASE_DENSITYDPI = 160;   //屏幕的像素密度      //以下三个变量为适配比例,即需要适配的设备和基准设备的屏幕参数比例      public static double widthRatio;            //宽度比例      public static double heightRatio;           //高度比例      public static double densityRatio;          //像素密度比例      //屏幕参数类型,分别表示宽度、高度和密度      public enum ScaleType {WIDTH, HEIGHT, DENSITY}      /** 初始化比例参数 */      public static void init(DisplayMetrics dm) {          widthRatio = dm.widthPixels / BASE_WIDTH;          heightRatio = dm.heightPixels / BASE_HEIGHT;          densityRatio = BASE_DENSITYDPI / dm.densityDpi;      }      /** 根据比例参数进行计算,并返回适配后的值 */      public static int resize(int size, ScaleType type) {          int result = 0;          switch (type) {          case WIDTH:              result = (int) (size * widthRatio);              break;          case HEIGHT:               result = (int) (size * heightRatio);              break;          case DENSITY:              result = (int) (size * densityRatio);              break;          }          return result;      }  } 

系统字体大小

从android4.0起系统设置的”显示“提供设置字体大小的选项。这个设置直接会影响到所有sp为单位的字体适配,所以很多app在设置了系统字体后瞬间变得面目全非。我们有俩种解决办法,第一种是把sp换成dp;第二种:通过代码的设置,使字体不根据系统字体改变,代码如下:

 @Override    public Resources getResources() {        Resources res = super.getResources();        Configuration config=new Configuration();        config.setToDefaults();        res.updateConfiguration(config, res.getDisplayMetrics());        return res;    }如果app中只是个别界面不需要,可改造下此方法 @Override    public Resources getResources() {        if(isNeedSystemResConfig()){            return super.getResources();        }else{            Resources res = super.getResources();              Configuration config=new Configuration();             config.setToDefaults();             res.updateConfiguration(config,res.getDisplayMetrics() );            return res;        }    }    // 默认返回true,使用系统资源,如果个别界面不需要,在这些activity中Override this method ,then return false;    protected boolean isNeedSystemResConfig() {        return true;    }

备注:这段代码得放在一个基类中(如baseActivity)。或者放在aplication中的oncreate方法中调用。

其它

不要用绝对布局,多使用match和wrap_content。可以考虑ScrollView 的使用。

Finally

目前就考虑到这么多,欢迎补充,欢迎交流。

0 0
原创粉丝点击