前言

网上关于屏幕适配的文章已经铺天盖地了,为什么还要讲?因为网上现在基本都是使用px适配,即每种屏幕分辨率的设备需要定义一套dimens.xml文件。再加上有些手机还有虚拟按键(例如华为),这样就还需要每个有虚拟按键的设备加多一套dimens.xml文件,再加上平板那些你会发现dimens.xml文件所占的体积已经超过2M了!这绝对不是我们想要的。

这里要讲的是使用dp来进行适配(Google推荐的也是这种方式),使用这种方式项目中多套dimens.xml文件才占几百K,而且根本不用考虑虚拟按键的问题。这种方案已经在自己多个项目中应用过了,经过几十台手机测试过,基本不会出现适配有问题的情况。制作生成对应dimens.xml文件插件的作者(后面会讲)android阿杜也说过他在待过的两家大公司实践过,所以请放心使用。

为什么要进行Android屏幕适配?

关于为什么要进行Android屏幕适配,什么是dp、dpi这些概念我就不去一一讲解了,网上很多文章。这里我推荐几篇讲的比较好的:

px与dp适配的原理

  • px适配原理:
    根据设备屏幕的分辨率各自写一套dimens.xml文件,然后根据一个基准分辨率(例如720x1080),将宽度分成720份,取值为1px——720px,将高度分成1080份,取值为1px——1080px。生成各自dimens.xml文件对应的值。

  • dp适配原理:
    dp适配原理与px适配一样,区别就在于px适配是根据屏幕分辨率,即拿px值等比例缩放,而dp适配是拿dp值来等比缩放而已。

问题:

  1. 既然原理都一样,都需要多套dimens.xml文件,为什么说dp适配就比px适配好呢?
    因为px适配是根据屏幕分辨率的,Android设备分辨率一大堆,而且还要考虑虚拟键盘。而dp适配无论手机屏幕的像素多少,密度比值多少,80%的手机的最小宽度dp值(widthPixels / density)都为360dp,这样就大大减少了dimens.xml文件。

  2. px适配会根据设备的分辨率去找对应的dimens.xml文件(如下图,运行在分辨率为1920x1080的手机上,系统会自动找到对应的values-1920x1080文件),那dp适配呢?

     
     

dp适配也是一样的,只不过dp适配是根据“最小宽度(Smallest-width)限定符”来找的,即如果当前设备最小宽度(以 dp 为单位)为400dp,那么系统会自动找到对应的values-sw400dp文件夹下的dimens.xml文件,如图

 
 

获取设备最小宽度代码

        DisplayMetrics dm = new DisplayMetrics();

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

        int widthPixels = dm.widthPixels;

        float density = dm.density;

        float widthDP = widthPixels / density;

使用步骤

1、以某一widthDP为基准,生成所有设备对应的dimens.xml文件

生成这些文件当然不会手动去写,网上已经有大神android阿杜提供了自动生成工具。

工具使用步骤:

  1. 在Android Studio中安装ScreenMatch插件,如图:
 
 
  1. 在项目的默认values文件夹中需要一份dimens.xml文件
    我在github源码已经提供了一份,直接复制过来即可。
 
 

github地址:ScreenAdaptation

  1. 执行生成
    插件安装好后,在项目的任意目录或文件上右键,选择ScreenMatch选项。如图:
 
 

然后选择在哪个module下执行适配。
即基于哪个module下的res/values/dimens.xml文件作为基准dimens.xml文件,生成的其他尺寸dimens.xml文件放在哪个module下。

 
 

点击确定就会执行生成命令,如下代表生成成功。

 
 

然后再看看res目录下会自动生成一堆dimens.xml文件,如下:

 
 

通过上面的步骤就已经生成了所有设备对应的dimens.xml文件。

因为默认生成的是下列最小宽度dp的dimens.xml文件
384,392,400,410,411,480,533,592,600,640,662,720,768,800,811,820,960,961,1024,1280,1365,如果不需要或者需要增加某些dp值的dimens.xml文件,则需要修改配置文件,即screenMatch.properties文件(修改前先删除之前生成的全部dimens.xml文件)。配置文件在我们执行完成上面的命令后,会在项目的目录下自动生成,如下:

 
 

打开文件,修改下面的值即可。如下只需要适配384,392,400,410,411的值,不需要适配480,533,592,600,640,662,720,768,800,811,820,960,961,1024,1280,1365的值

 
 

其中base_dp=360代表widthDP基准值,一般都是360dp,不建议更改,除非你对屏幕适配原理有深刻的见解。

当然!这些步骤你可以全部都不用做。直接复制我github上的各个dimens.xml文件到你项目即可!这些都是我在真实项目中使用的。

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

在安卓中,系统密度为160dpi的中密度手机屏幕为基准屏幕,即320×480的手机屏幕。在这个屏幕中,1dp=1px。320x480分辨率对应的其他分辨率的比例如下:

 
image.png

图片来源:UI设计师不可不知的安卓屏幕知识

所以,如果UI给的是720x1280分辨率的图, 那么dp = px / 2, 给的是1080x1920分辨率的图,那么 dp = px / 3,即根据比例即可。

举例:UI在720x1280上做的图,其中一个按钮的宽高分辨为:宽720px,高为100px,字体大小为30px,在布局中则这样使用:

    <Button
android:layout_width="@dimen/dp_360"
android:layout_height="@dimen/dp_50"
android:textSize="@dimen/sp_15"/>

代码中动态设置dp或sp:
如果需要在代码中动态设置dp或sp,则需要通过getDimension()方法获取对应资源文件下的dp或sp值再设置(具体参考github上的demo)。如下:

        /*获取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值

怎么适配其他module?

  • 问题:在项目的其他module中怎么实现适配?难道也要多套dimens?
  • 解决:并不需要多套dimens,只需要在values文件夹下有一套与app module一样的dimens文件即可达到适配。因为经过编译,所有module中的dimen数据都会统一归类到主module(即app module)中的values/dimens.xml文件中了,然后系统又会根据你设置的值去找对应values-swxxxdp文件夹下的dimens.xml文件中的值。
  • 验证:在项目中建一个module,然后随便取一个dimens.xml文件中的值进行打印,分别运行在不同widthDP的设备上(用模拟器即可)观察打印的结果发现确实是这样的。

最后非常感谢大神android阿杜提供的插件,具体的dp适配与插件原理可以去看看他写的文章。

github地址:ScreenAdaptation

参考资料:

好用的Android屏幕适配的更多相关文章

  1. Android屏幕适配全攻略 (转载)

    http://blog.csdn.net/jdsjlzx/article/details/45891551 https://github.com/hongyangAndroid/AndroidAuto ...

  2. 【收藏】Android屏幕适配全攻略(最权威的Google官方适配指导)

    来源:http://blog.csdn.net/zhaokaiqiang1992 更多:Android AutoLayout全新的适配方式, 堪称适配终结者 Android的屏幕适配一直以来都在折磨着 ...

  3. Android屏幕适配全攻略(最权威的官方适配指导)(转),共大家分享。

    Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的官方文档为基础,全面而深入的讲解了Android屏幕适配的原因.重要概念.解决方案及最佳实践,我相信如果你能认真的学习 ...

  4. Android屏幕适配全攻略(最权威的官方适配指导) (转)

    招聘信息: Cocos2d-X 前端主程 [新浪微博]手机客户端iOS研发工程师 20k-40k iOS 开发工程师 iOS高级开发工程师(中国排名第一的企业级移动互联网云计算公司 和创科技 红圈营销 ...

  5. 腾讯优测| 让Android屏幕适配开发更简单-Google百分比布

    文/腾讯优测工程师 吴宇焕 腾讯优测优社区干货精选~ 相信开发同学都被安卓设备碎片化的问题折磨过,市面上安卓手机的主流屏幕尺寸种类繁多,给适配造成很大的困难.就算搞定了屏幕尺寸问题,各种分辨率又让人眼 ...

  6. Android 屏幕适配(一)百分比布局库(percent-support-lib) 解析与扩展

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/46695347: 本文出自:[张鸿洋的博客] 一.概述 周末游戏打得过猛,于是周 ...

  7. Android重写getResources规避用户调整系统字体大小影响Android屏幕适配

    Android屏幕适配一直是一个头疼的问题.除此之外还要考虑APP在实际应用场景中,用户千奇百怪的设置,最常见的用户设置行为就是设置手机的字体大小,比如把字体设置成超大或者超小,这对屏幕适配又带来额外 ...

  8. (转)android屏幕适配

    声明:eoe文章著作权属于作者,受法律保护,转载时请务必以超链接形式附带如下信息 原文作者: zhuangyujia 原文地址: http://my.eoe.cn/zhuangyujia/archiv ...

  9. 【转】Android屏幕适配全攻略(最权威的官方适配指导)

    原文网址:http://blog.csdn.net/jdsjlzx/article/details/45891551 Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的 ...

  10. Android开发——自动生成Android屏幕适配的dimens.xml文件

    使用dimens.xml解决屏幕适配问题是Android官方解决方案,本文主要讲述了如何自动生成Android屏幕适配的dimens.xml,减少了工作量,在维护dimens.xml文件时更加省时省力 ...

随机推荐

  1. thinkphp下实现ajax无刷新分页

    1.前言 作为一名php程序员,我们开发网站主要就是为了客户从客户端进行体验,在这里,thinkphp框架自带的分页类是每次翻页都要刷新一下整个页面,这种翻页的用户体验显然是不太理想的,我们希望每次翻 ...

  2. python笔记四:面向对象

    1.类 class Student(object): def __init__(self, name, score): self.name = name self.score = score 1)__ ...

  3. Android,几款apk工具

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 可以查看到链接的设备 可以查看到wifi密码,这个也是个开源的 可以查询驾照学时进度 可 ...

  4. [BZOJ2669][CQOI2012]局部最小值(容斥+状压DP)

    发现最多有8个限制位置,可以以此为基础DP和容斥. $f_{i,j}=f_{i-1,j}\times (cnt_j-i+1)+\sum_{k\subset j} f_{i-1,k}$ $cnt_j$表 ...

  5. 数据库之mysql的基本操作

    1 数据库 1.1 数据库介绍 为什么要有数据库? 数据需要大量的存储,把数据永久保存下来,可以保存到文件中,当然也可以保存到数据库中. 数据库:通俗的说,存储数据的仓库,是管理数据的文件夹:存放数据 ...

  6. Problem F: 尖兵

    #include<stdio.h> struct man{ ]; int grade; }; int main(void) { int t; int i,j,n; ],max; scanf ...

  7. [转]spring property标签中的 ref属性和ref 标签有什么不同

    spring property标签中的 ref属性和ref 标签有什么不同? 如下:<property name="a" ref="b" /> sp ...

  8. CDOJ 1277 智商杯考试 每周一题 div2 二分+数学

    智商杯考试 题目连接: http://acm.uestc.edu.cn/#/problem/show/1277 Description 你是一个挂科选手. 你现在正在考试,你很方. 你参加的考试叫做智 ...

  9. oracle增加表空间的四种方法

    1. 查看所有表空间大小 select tablespace_name,sum(bytes)/1024/1024 from dba_data_files group by tablespace_nam ...

  10. GDB的一些技巧

    查看栈信息 bt info stack 查看源程序 list ctrl + x + a 分屏调试,上半部分显示代码,下半部分显示调试信息. 查看内存 p  xxxptr@n  查看xxxptr 指针内 ...