Android 一种非常好用的Android屏幕适配
前言
网上关于屏幕适配的文章已经铺天盖地了,为什么我还要讲?因为网上现在基本都是使用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值来等比缩放而已。
问题:
既然原理都一样,都需要多套dimens.xml文件,为什么说dp适配就比px适配好呢?
因为px适配是根据屏幕分辨率的,Android设备分辨率一大堆,而且还要考虑虚拟键盘。而dp适配无论手机屏幕的像素多少,密度比值多少,80%的手机的最小宽度dp值(widthPixels / density)都为360dp,这样就大大减少了dimens.xml文件。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 heightPixels = dm.heightPixels;
int widthPixels = dm.widthPixels;
float density = dm.density;
float heightDP = heightPixels / density;
float widthDP = widthPixels / density;
float smallestWidthDP;
if(widthDP < heightDP) {
smallestWidthDP = widthDP;
}else {
smallestWidthDP = heightDP;
}
使用步骤
1、以某一widthDP为基准,生成所有设备对应的dimens.xml文件
生成这些文件当然不会手动去写,网上已经有大神android阿杜提供了自动生成工具。
工具使用步骤:
- 在Android Studio中安装ScreenMatch插件,如图:

- 在项目的默认values文件夹中需要一份dimens.xml文件
我在github源码已经提供了一份,直接复制过来即可。

github地址:ScreenAdaptation
- 执行生成
插件安装好后,在项目的任意目录或文件上右键,选择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分辨率对应的其他分辨率的比例如下:

图片来源: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 一种非常好用的Android屏幕适配的更多相关文章
- [原创]一种Unity2D多分辨率屏幕适配方案
此文将阐述一种简单有效的Unity2D多分辨率屏幕适配方案,该方案适用于基于原生开发的Unity2D游戏,即没有使用第三方2D插件,如Uni2D,2D toolkit等开发的游戏,NGUI插件不受这个 ...
- 一种Unity2D多分辨率屏幕适配方案
http://www.cnblogs.com/flyFreeZn/p/4073655.html 此文将阐述一种简单有效的Unity2D多分辨率屏幕适配方案,该方案适用于基于原生开发的Unity2D游戏 ...
- Android四种基本布局(LinearLayout \ RelativeLayout \ FrameLayout \ TableLayout)
------------------------------------------LinearLayout---------------------------------------------- ...
- Android三种基本的加载网络图片方式(转)
Android三种基本的加载网络图片方式,包括普通加载网络方式.用ImageLoader加载图片.用Volley加载图片. 1. [代码]普通加载网络方式 ? 1 2 3 4 5 6 7 8 9 10 ...
- Android 三种动画详解
[工匠若水 http://blog.csdn.net/yanbober 转载请注明出处.点我开始Android技术交流] 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让 ...
- android 四种堆状态
总结下: ====> 建议首先阅读下面两篇文章,这样才可以更好的理解Activity的加载模式: Android的进程,线程模型 http://www.cnblogs.com/ghj1976/a ...
- 【Android 复习】:Android五种布局的使用方法
---恢复内容开始--- 在Android布局中,有五种常用的布局,下面我们就来学习一下这几种布局的使用方式 1) 线性布局:LinearLayout 2) 帧布局: FrameLayout 3) ...
- Android中实现全屏、无标题栏的两种办法(另附Android系统自带样式的解释)
在进行UI设计时,我们经常需要将屏幕设置成无标题栏或者全屏.要实现起来也非常简单,主要有两种方法:配置xml文件和编写代码设置. 1.在xml文件中进行配置 在项目的清单文件AndroidManife ...
- android五种布局模式
Android布局是应用界面开发的重要一环,在Android中,共有五种布局方式,分别是:LinearLayout (线性布局),FrameLayout(框架布局),AbsoluteLayout(绝对 ...
随机推荐
- flask _bootstrap中使用flash
在模板中获取flash闪现的那段代码要和内容块放在同一级别上.不然网页上是看不到闪现的内容的. 比如在基模板里定义一个content block ,里面一个是get_flashed_messages代 ...
- win8.1中向IIS注册asp.net
以前都是用aspnet_regiis -I 命令向IIS注册asp.net ,今天换了win8.1后竟然发现这招不好使了. 根据提示,需要用dism.exe来完成注册. 折腾一会儿后,问题最终解决: ...
- 【并行】Ubuntu安装MPI库
1.环境搭建 终端:sudo apt-get install mpich2 安装的是mpich2的1.4.1版本. 2.编译 终端:mpicc mpi_hello.c -g -Wall -o mpi_ ...
- C# 数组基础
一.数组的基础知识 1.数组有什么用? 如果需要同一个类型的多个对象,就可以使用数组.数组是一种数组结构,它可以包含同一个类型的多个元素. 2.数组的初始化方式 第一种:先声明后赋值 ]; array ...
- docker 日志管理
高效的监控和日志管理对保持生产系统持续稳定地运行以及排查问题至关重要. 在微服务架构中,由于容器的数量众多以及快速变化的特性使得记录日志和监控变得越来越重要.考虑到容器短暂和不固定的生命周期,当我们需 ...
- web操作文件的上传到服务器 并可下载 并且读取出来
1.文件的上传-servlet实现文件上传---核心API—DiskFileItemFactory 一.文件上传概述 l 实现web开发中的文件上传功能,需完成如下二步操作: • 在web页面 ...
- ClouderManager集群在Linux里浏览器默认是英文,在Win里浏览器是中文,怎么更改?(图文详解)
不多说,直接上干货! 问题详情 在这里面如何英文改中文的吗? 莫非要把linux的语言环境给改了?? 我找找网页的语言字体怎么更改下 找到对应页面,修改成中文 解决办法 刷新下,即可 欢迎大家,加入我 ...
- python-单链表的实现
#!/usr/bin/python class Node(object): def __init__(self,value,next=None): self.value,self.next=value ...
- redis实战笔记(1)-第1章 初识Redis
第1章 初识Redis 注:本书在redis3.0版本的,比如redis3.0以后支持服务端集群.3.0之前只能客户端分片. 本章主要内容 1.Redis与其他软件的相同之处和不同之处 2.Re ...
- 开始使用 Vuejs 2.0 ---简单总结1
Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vuejs 采用自底向上增量开发的设计.Vuejs 的核心库只关注视图层,并且非常容 ...
