一 前言
众所周知,Android厂商非常多,各种尺寸的Android手机、平板层出不穷。导致了Android生态环境的碎片化现象越来越严重。
Google公司为了解决分辨率过多的问题,在Android的开发文档中定义了px,dp,dip,sp,方便开发者适配不同分辨率的Android设备。
二 基础知识
mm: millimeters(毫米)----长度单位
in: inches (英寸)----长度单位,屏幕物理尺寸大小的基本单位
pt: points (磅)----一个标准单位,大小为一英寸屏幕大小的1/72,即1pt = 1/72in
dpi: dots per inch(像素密度)----每英寸的像素点
举个例子帮助理解:
假设QVGA (320*240)分辨率的屏幕物理尺寸是2英寸*1.5英寸,则这部手机的dpi= 160,即每英寸具有160个像素点。
Screen size(屏幕尺寸)指的是手机实际的物理尺寸。 如iPhone4S是3.5英寸,这里的3.5英寸指的是手机屏幕对角线的长度为3.5英寸。
三 屏幕分辨率
QVGA(240×320像素)、
HVGA(480×320像素)、
WVGA(800×480像素)、
720P(1280x720像素)、
1080P(1920x1080像素)、
2K(2560x1440像素)
四 dp(dip)、px、pt、sp之间的区别
px: pixel(像素) ----屏幕上的点,不建议使用
1px代表屏幕上的一个物理的像素点。但px单位不被建议使用。因为同样像素大小的图片在不同手机显示的实际大小可能不同。
要用到px的情况是需要画1像素表格线或阴影线的时候,如果用其他单位画则会显得模糊。
dp (dip): device independent pixel(设备独立像素)----建议使用(宽度、高度等)
dp与dip相同 ,dp是最常用也是最难理解的尺寸单位。,与密度无关的像素,一种基于屏幕密度的抽象单位,在每英寸160点的显示器上,1px = 1dp;
一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。
Android系统定义了四种像素密度:低(120dpi)、中(160dpi)、高(240dpi)和超高(320dpi), 它们对应的dp到px的系数分别为0.75、1、1.5和2,这个系数乘以dp长度就是像素数。例如界面上有一个长度为“80dp”的图片,那么它在240dpi的手机上实际显示为80x1.5=120px,在320dpi的手机上实际显示为80x2=160px。如果你拿这两部手机放在一起对比,会发现这个图片的物理尺寸“差不多”,这就是使用dp作为单位的效果。
sp: Scale-independent Pixel(放大像素)----建议使用(字体大小等)
主要用于字体显示best for textsize。 与密度无关的像素,与dp类似,但是可以根据用户的字体大小首选项进行缩放;
sp和dp很类似但唯一的区别是,Android系统允许用户自定义文字尺寸大小(小、正常、大、超大等等),当文字尺寸是“正常”时, 1sp=1dp=0.00625英寸,而当文字尺寸是“大”或“超大”时,1sp>1dp=0.00625英寸。类似我们在windows里调整字体尺寸以后的效果——窗口大小不 变,只有文字大小改变。
pt: point(磅) ----是一个标准的长度单位
由此,根据 google 的建议,TextView 的字号最好使用 sp 做单位,而且查看TextView的源码可知 Android 默认使用 sp 作为字号单位。
还有, google代码里边所用的单位都是以px为默认单位的.
五 像素选择
apk的资源包中
当屏幕density=160时,使用mdpi标签的资源
当屏幕density=120时,使用ldpi标签的资源。
在每英寸160点的显示器上,1dp = 1px。
public static int dip2px(Context context, float dipValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dipValue * scale + 0.5f);
}
public static int px2dip(Context context, float pxValue){
final float scale = context.getResource().getDisplayMetrics().density;
return (int)(pxValue / scale + 0.5f);
}
public static int dip2px(Context context, float dipValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dipValue * scale + 0.5f);
}
public static int px2dip(Context context, float pxValue){
final float scale = context.getResource().getDisplayMetrics().density;
return (int)(pxValue / scale + 0.5f);
}
下面说下如何获取分辨率:
在一个Activity的onCreate方法中,写入如下代码:
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5)
int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240)