概述:
在做屏幕适配之前先搞清楚的概念:
屏幕尺寸
屏幕尺寸指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米比如常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等
屏幕分辨率
屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1个像素点。一般以纵向像素*横向像素,如1960*1080。屏幕像素密度
屏幕像素密度是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。dp、dip、dpi、sp、px
px我们应该是比较熟悉的,前面的分辨率就是用的像素为单位,大多数情况下,比如UI设计、Android原生API都会以px作为统一的计量单位,像是获取屏幕宽高等。dip和dp是一个意思,都是Density Independent Pixels的缩写,即密度无关像素,上面我们说过,dpi是屏幕像素密度,假如一英寸里面有160个像素,这个屏幕的像素密度就是160dpi,那么在这种情况下,dp和px如何换算呢?在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px,以此类推。
假如同样都是画一条320px的线,在480*800分辨率手机上显示为2/3屏幕宽度,在320*480的手机上则占满了全屏,如果使用dp为单位,在这两种分辨率下,160dp都显示为屏幕一半的长度。这也是为什么在Android开发中,写布局的时候要尽量使用dp而不是px的原因。
而sp,即scale-independent pixels,与dp类似,但是可以根据文字大小首选项进行放缩,是设置字体大小的御用单位。
mdpi、hdpi、xdpi、xxdpi
其实之前还有个ldpi,但是随着移动设备配置的不断升级,这个像素密度的设备已经很罕见了,所在现在适配时不需考虑。mdpi、hdpi、xdpi、xxdpi用来修饰Android中的drawable文件夹及values文件夹,用来区分不同像素密度下的图片和dimen值。
那么如何区分呢?Google官方指定按照下列标准进行区分:
使用dp作单位:
使用dp作单位可以自适应主流的手机,但并不是所有的,例如:
红米note2:
dm == DisplayMetrics{density=3.0, width=1080, height=1920, scaledDensity=3.0, xdpi=403.411, ydpi=403.041}
width == 1080px = 360dp
height == 1920px = 640dp
MX4:
dm == DisplayMetrics{density=3.0, width=1152, height=1920, scaledDensity=3.0, xdpi=418.011, ydpi=416.82}
width == 1152px = 384dp
height == 1920px = 640dp
可以看出红米note2和MX4的屏幕像素密度相同,但是屏幕分辨率不同,所以如果设置width = 360dp,在红米note2上可以填满屏幕,但是在MX4上就不会。
一句话,总结下,dp能够让同一数值在不同的分辨率展示出大致相同的尺寸大小。但是当设备的尺寸差异较大的时候,就无能为力了。
这里有一些适配的小技巧:
多用match_parent
多用weight
自定义view解决
还有一种方式是根据文件来适配:
光看dpi也不行,也要看对应的屏幕最小宽度,这个最小宽度是和dp对应的,用下列代码既可:
Configuration config = getResources().getConfiguration();
int smallestScreenWidth = config.smallestScreenWidthDp;
L.i("smallest width : "+ smallestScreenWidth);
这个获取出来的值,我们需要建立对应的values-sw{smallestWidth}dp文件夹进行适配,以上是文字和距离尺寸的适配
使用百分比布局:
Android 5.0 Google官方推出了百分比布局支持库,意在解决大部分屏幕适配的问题。但是还是存在不少的缺点:
当使用图片时,无法设置宽高的比例
很难使用百分比定义一个正方形的控件
一个控件的margin四个方向值一致
dependencies {
compile 'com.android.support:percent:22.2.0'
}
在此基础上有好多大牛进行了再次封装,使得功能大大完善,例如鸿洋封装的:
用法也简单:
先引入jar包
dependencies { compile 'com.zhy:percent-support-extends:1.0.1' }然后添加命名空间
xmlns:app="http://schemas.android.com/apk/res-auto"接着就可以直接使用了,如下:
<?xml version="1.0" encoding="utf-8"?> <com.zhy.android.percent.support.PercentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.zhy.android.percent.support.PercentFrameLayout android:layout_width="0dp" android:layout_height="0dp" android:layout_gravity="center" android:background="#ff44aacc" app:layout_heightPercent="50%w" app:layout_widthPercent="50%w"> <com.zhy.android.percent.support.PercentFrameLayout android:layout_width="0dp" android:layout_height="0dp" android:layout_gravity="center" android:background="#ffcc5ec7" app:layout_heightPercent="50%w" app:layout_widthPercent="50%w"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:background="#ff7ecc16" android:gravity="center" android:text="margin 15% of w" app:layout_marginPercent="15%w" /> </com.zhy.android.percent.support.PercentFrameLayout> </com.zhy.android.percent.support.PercentFrameLayout> <TextView android:layout_width="0dp" android:layout_height="0dp" android:layout_gravity="bottom|right" android:background="#44ff0000" android:gravity="center" android:text="15%w,15%w" app:layout_heightPercent="15%w" app:layout_marginPercent="5%w" app:layout_widthPercent="15%w"/> </com.zhy.android.percent.support.PercentFrameLayout>