相信做手机端的 App 的小伙伴,只要是产品稍微大一点,就会面临屏幕适配的问题,对于适配这个问题,网上众说纷纭,以前虽然有零零散散的看过,但是没有实践过,也是在最近遇到这个需求的情况下才研究了一下,现在做个记录。
http://blog.csdn.net/qq_34161388/article/details/73469319
首先需要明白一些概念,比如什么是 px,什么是 dp,什么是 dpi,讲这些概念的文章很多,推荐一个:
http://www.jianshu.com/p/ec5a1a30694b
Google 官方推荐在写布局文件的时候使用 dp,在分辨率相差不大的情况下,dp 确实能自己进行一定适配,但是如果分辨率比较大的时候,还是会有问题,随便写个布局:
-
xml version=“1.0” encoding=“utf-8”?>
-
<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
-
android:layout_width=
“match_parent”
-
android:layout_height=
“match_parent”>
-
-
<ImageView
-
android:layout_width=
“100dp”
-
android:layout_height=
“100dp”
-
android:layout_marginLeft=
“100dp”
-
android:layout_marginTop=
“250dp”
-
android:src=
“@mipmap/ic_launcher” />
-
RelativeLayout>
上面两个图,左边是Galaxy Core mini,分辨率为 800x480,右边是魅蓝 metal,分辨率 1920x1080,可以看到还是有明显差别的,这个时候我们就应该想到适配,那么适配的方式有很多,比如洋神的 AutoLayout(已经停止维护了,不建议在项目中使用),还有写多个 layout 布局呀,还有 dimens 适配呀等等,在对比了多种方法后,最后我采用了 dimens 适配这种方式。这样的适配方式虽然会加入很多不同分辨率的 dimens 文件,但是比起写多个 layout 布局,要修改 UI 的时候需要修改很多 layout 的情况,还是要方便一点,最主要的是写布局的时候方便一点。
使用方法也就是建立多个不同分辨率的 values 文件夹,比如主流的分辨率:values-800x480、values-1280x720、values-1920x1080,而在 Android 中规定是以 480x320 为基准的,所以这个可以放到默认的 values 文件夹下:
然后在每个文件夹下放对应的 dimens.xml 文件。比如默认的 values 文件夹下面的 dimens 文件是这样的:
-
pxml version="1.0" encoding="utf-8"?>
-
<resources>
-
<dimen name="px1">1px
dimen>
-
<dimen name="px2">2px
dimen>
-
<dimen name="px3">3px
dimen>
-
<dimen name="px4">4px
dimen>
-
......
-
<dimen name="px1397">1397px
dimen>
-
<dimen name="px1398">1398px
dimen>
-
<dimen name="px1399">1399px
dimen>
-
<dimen name="px1400">1400px
dimen>
-
-
resources>
-
pxml version="1.0" encoding="utf-8"?>
-
<resources>
-
<dimen name="px1">2.25px
dimen>
-
<dimen name="px2">4.5px
dimen>
-
<dimen name="px3">6.75px
dimen>
-
<dimen name="px4">9px
dimen>
-
......
-
<dimen name="px1397">3143.25px
dimen>
-
<dimen name="px1398">3145.5px
dimen>
-
<dimen name="px1399">3147.75px
dimen>
-
<dimen name="px1400">3150px
dimen>
-
-
resources>
-
pxml version="1.0" encoding="utf-8"?>
-
<resources>
-
<dimen name="px1">3.375px
dimen>
-
<dimen name="px2">6.75px
dimen>
-
<dimen name="px3">10.125px
dimen>
-
<dimen name="px4">13.5px
dimen>
-
......
-
<dimen name="px1397">4714.875px
dimen>
-
<dimen name="px1398">4718.25px
dimen>
-
<dimen name="px1399">4721.625px
dimen>
-
<dimen name="px1400">4725px
dimen>
-
-
resources>
你没看错,就是 px,这样我们可以直接用 px 来写布局文件了,而不用对着设计图去换算了,而且我们既然可以将 480x320 的分辨率作为基准,那么同样也可以以我们的设计图的分辨率作为基准,比如我是以 1280x720 作为基准的,只要比例不变就行了,如果以 1280x720 为基准,那么 values-1920x1080 的 dimens 则应该是:
-
pxml version="1.0" encoding="utf-8"?>
-
<resources>
-
<dimen name="px1">1.5px
dimen>
-
<dimen name="px2">3px
dimen>
-
<dimen name="px3">4.5px
dimen>
-
<dimen name="px4">6px
dimen>
-
......
-
<dimen name="px1397">2095.5px
dimen>
-
<dimen name="px1398">2097px
dimen>
-
<dimen name="px1399">2098.5px
dimen>
-
<dimen name="px1400">2100px
dimen>
-
-
resources>
这样设计图上是多少我们就写多少,再也不用去换算了。
但是这么多 dimens 文件不可能手写,推荐一个 dimens 文件自动生成器:
作为程序猿的我们当然不会做手写的这些蠢事!!!多谢 @鸿洋大神 提供了自动生成工具(内置了常用的分辨率),大家可以直接点击这里下载
注:工具默认基准为400*320,当然对于特殊需求,通过命令行指定即可:
java -jar 文件名.jar 基准宽 基准高 额外支持尺寸1的宽,额外支持尺寸1的高_额外支持尺寸2的宽,额外支持尺寸2的高:
例如:需要设置的基准是800x1280,额外支持尺寸:735x1152 ;3200x4500;
java -jar 文件名.jar 800 1280 735,1152_3200,4500
有的手机是有虚拟按键的,比如 nexus、华为,这些有虚拟按键的手机,分辨率是将虚拟按键的高度算进去了的,但是 Android 在对 values 适配的时候却不会将虚拟按键的高度算进去,比如一个手机的分辨率本来是 1920x1080,但是虚拟按键栏占了120,那么真实高度就是1800,在适配的时候就不会去找1920x1080了,而是会去找低一级的分辨率了,比如 1280x720了,那么布局又会出问题了,怎么办呢?既然它算的时候就没有算虚拟按键栏的高度,那么我们可以获取虚拟按键栏的高度:
-
/**
-
* Description:获取屏幕真实高度(不包括虚拟按键栏)
-
* Date:2017/9/2
-
*/
-
public static int getScreenHeight(Context context) {
-
return context.getResources().getDisplayMetrics().heightPixels;
-
}