我们之前了解过屏幕的像素密度 dpi,我们身边有很多种类的手机,它们的dpi各不相同,我们如何去适配这些不同的屏幕呢?
单位
务必使用dp
或者sp
;dp
是一种非密度制约像素,其尺寸与 160 dpi 像素的实际尺寸相同,即对应mdpi
下的尺寸。sp
也是一种基本单位,它用于设置文字的大小,它可以根据我们设置的文字大小进行调整,类似于dp,但是它只适用于文字的大小的设置,不能设置布局的尺寸。
默认的我们的工程创建完毕之后,会有一个values的文件夹用来存放一些资源,这里会有一个dimens.xml文件,里面保存的都是一些尺寸,不管是图片、布局的宽高,还是文字的大小都可以引用这里的尺寸。
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
我们在布局里使用时,就可以像这样
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/activity_horizontal_margin"
android:orientation="vertical">
</LinearLayout>
为了适应多种布局,我们需要在不同的屏幕密度下使用不同的values文件来引用尺寸,我们在前面说过各个屏幕密度对应的文件夹。
名称 | 像素密度范围 |
---|---|
mdpi | 120dpi-160dpi |
hdpi | 160dpi-240dpi |
xhdpi | 240dpi-320dpi |
xxhdpi | 320dpi-480dpi |
xxxhdpi | 480dpi-640dpi |
我们为了在不同的屏幕上显示的效果都相似,需要创建values-mdpi
,values-hdpi
,values-xhdpi
,values-xxhdpi
,values-xxxhdpi
等文件夹,在每个文件夹下的dimens.xml文件里定义我们需要的尺寸,到时候系统会根据屏幕的分辨率自动去各个对应的文件夹下去找对应的尺寸。
对于图片也是一样,我们可以分别创建 drawable-mdpi
,drawable-hdpi
,drawable-xhdpi
,drawable-xxhdpi
,drawable-xxxhdpi
等文件夹,分别放置不同尺寸的图片,显示在不同的分辨率的手机上。
比如我们的美工设计的时候是按照 1280x720
,4.65 寸的手机设计的UI, 某张图的尺寸是200x200,那么我们应该怎么往各个文件夹下放置图片呢?
我们可以计算根据公式
计算出美工设计的是 在 xhdpi 下的图,切出来的图是200x200,可以直接放到
drawable-xhdpi
下,那么其它的文件夹呢?我们知道
mdip:hdpi:xhdpi:xxhdip:xxxhdpi = 2:3:4:6:8,根据比例我们也可看出其它的文件夹下放置的图片的尺寸了,xxxhdip
,xxhdpi
,hdpi
、mdpi
下的图的尺寸应该是 400x400,300x300,150x150,100x100。到时候我们就可以问美工要来这些尺寸进行适配了。
同样的算法也适用于values下的dimens中的尺寸,比如美工也是按照 1280x720
,4.65 寸的手机设计的UI,标准其中一个控件的宽度为200px,那么我们应该怎么计算其它dpi下的尺寸呢?我们知道在Android系统中是以160dpi 为标准线,在密度为160dpi的手机上1px = 1dp,即mdpi下的尺寸对应的是 1px = 1dp,而我们又知道mdip:hdpi:xhdpi:xxhdip:xxxhdpi = 2:3:4:6:8,根据这些,我们可以知道dp和px之间的换算公式:
比如我们现在的dpi为315,设计的宽度为 200px,那么对应的dp值为
由此我们得出了 xhdpi下的尺寸为101.6dp,按比例我们再把其它dpi下的尺寸算出就OK了。
除了这样算values下的 dimens 中的尺寸,我们还可以按照下面的比例来算:
像素密度等级 | 像素密度与dp转换关系 |
---|---|
mdpi | 1dp = 1px |
hdpi | 1dp = 1.5px |
xhdpi | 1dp = 2px |
xxhdpi | 1dp = 3px |
xxxhdpi | 1dp = 4px |
我们可以看出这张表也是根据2:3:4:6:8这个比例来,不管使用哪种方式,误差肯定是存在的,不过这些误差都是在可接受的范围。可以根据我们的具体情况来选用。