分辨率,这个在android平台上异常麻烦的问题,让很多新手要崩溃了。今天,我想和分辨率这个家伙谈谈。
首先,什么是分辨率呢?我们通常说的480*800、1280*720等等,就是所谓的手机屏幕的分辨率。分辨率代表的是整个屏幕上,一共有多少个像素点,也就是在ps或者是其他的图像编辑软件中的px的概念。美工在帮我们做高清原型图的时候,一般会按照多少分辨率来做。这里提醒一下刚入职的新手,android版本的高清原型图最好选择1280*720像素,这样美工在后期的切图的时候会比较容易。目前的项目因为分辨率选择的是480*800,所以在后期做高分辨率适配的时候,有很多的小图标需要重做,否则显示效果很模糊,这无形之中加大了UI设计师的工作量,算是一个教训吧!
但是呢,我们开发者在用xml写界面的时候,可不会直接用px做为单位,这是因为在不同的分辨率下面,相同显示效果的界面上,控件的实际像素并不是一样的,因此,我们在设置控件大小的时候,一般用的是dip(dp)作为长度单位,那么,dip到底是一种什么单位呢?
dip是Density independent pixel的缩写,也就是独立的像素密度的意思,dip是基于屏幕密度的抽象单位,与设备无关,用于说明与密度无关的尺寸和位置。它是相对于一个160dpi的屏幕来说的,因此1dip对应160dpi屏幕上的1px。
这里一定要注意,dip和dpi是截然不同的两个概念,不要弄混。
dip指的是一种独立像素的表示方式,它的计算是在dpi的基础之上的,也就是说,我们只有在知道dpi是多少之后,才能够根据不同的dpi,来精确计算我们需要的dip。
dpi是一种密度单位,是dot
per inch的缩写,也就是每英寸多少个像素点的意思。比如说,我们有一个480*800分辨率的手机,屏幕的物理尺寸是3英寸*5英寸,那么我们就可以计算出这个手机的是480/3=160dpi,是属于低分辨率的,那么在这种分辨率下面,一个dip就相当于1个px,怎么计算呢?当然就是1dip*(160/160)=1px。也就是说,当我们在这种分辨率的手机下,控件的宽度和长度就和设计图一样大小就可以,一个dip对应一个px。但是,如果还是相同的分辨率,换成了2英寸*3.3英寸呢?那么我们就可以先算出手机的密度是480/2=240dpi,是属于高分辨率的,那么在这种分辨率下面,一个dip就相当于1.5像素,怎么计算呢?当然还是1dip*(240/160)=1.5px。
因此,明白了dip和dpi的关系,我们就可以精确的设定控件的大小。
具体而言,当屏幕的的分辨率为320x480时,无论实际的物理尺寸大小,密度都会被设置为160dpi,也就意味着这个设备上,一行最多可以放置320dp,而对于480x800的设备,只需屏幕尺寸在3寸到4.3寸之间,密度都会被设置为240dpi,一行同样可以放置320dp。因此在开发中,用dp作为单位,只需要设置一次,就可以适配到多个屏幕上。
现在我们清楚了这两个名词之间的关系,那么,我们在程序中,如何对两者进行转换呢?
下面的代码,可以帮助我们实现dp到px的转换
<span style="font-size:18px;">/** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { //获取当前屏幕密度dpi与基础密度160dpi的倍数关系,+0.5f是为了保证转化成int类型时的数据正确 float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); }</span>
我们也可以实现px到dp的转换
<span style="font-size:18px;">/** * 根据手机的分辨率从 px(像素) 的单位 转成为 dp */ public static int px2dip(Context context, float pxValue) { //获取当前屏幕密度dpi与基础密度160dpi的倍数关系,+0.5f是为了保证转化成int类型时的数据正确 float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); }</span>