dp: 一个基于density的抽象单位,如果一个160dpi的屏幕,1dp=1px
dip: 等同于dp。Density independent pixels ,设备无关像素。
sp: 同dp相似,但还会根据用户的字体大小偏好来缩放(建议使用sp作为文本的单位,其它用dip)
dpi: dots per inch , 直接来说就是一英寸多少个像素点。常见取值 120,160,240。我一般称作像素密度,简称密度
density: 直接翻译的话貌似叫 密度。常见取值 1.5 , 1.0 。和标准dpi的比例(160px/inc)
屏幕尺寸: 屏幕对角线的长度。电脑电视同理。
屏幕比例的问题。因为只确定了对角线长,2边长度还不一定。所以有了4:3、16:9这种,这样就可以算出屏幕边长了。
计算dpi
比如一个机器,屏幕4寸,分辨率480X800,他的dpi能算么。因为不知道边长,肯定不能分开算,4是对角线长度,那直接用勾股定理算对角线像素,除以4,算出来大概是 dpi = 233 像素/英寸。那么density就是 (233 px/inch)/(160 px/inch)=1.46 左右。
android默认的只有4个dpi,low、medium、high、xh,对应 120、160、240、320,其中的default就是160。
dp与px换算公式:
pixs =dips * (densityDpi/160).
dips=(pixs*160)/densityDpi
但是我们在代码里面进行转化的时候还需要有一个偏移值:0.5f
- private static final float scale = mContext.getResources().getDisplayMetrics().density;
- private static final float scaledDensity = mContext.mContext.getResources().getDisplayMetrics().scaledDensity;
- /**
- * dp转成px
- * @param dipValue
- * @return
- */
- public static int dip2px(float dipValue) {
- return (int) (dipValue * scale + 0.5f);
- }
- /**
- * px转成dp
- * @param pxValue
- * @return
- */
- public static int px2dip(float pxValue) {
- return (int) (pxValue / scale + 0.5f);
- }
- /**
- * sp转成px
- * @param spValue
- * @param type
- * @return
- */
- public static float sp2px(float spValue, int type) {
- switch (type) {
- case CHINESE:
- return spValue * scaledDensity;
- case NUMBER_OR_CHARACTER:
- return spValue * scaledDensity * 10.0f / 18.0f;
- default:
- return spValue * scaledDensity;
- }
- }
为什么我们在布局的时候最好要用dip,不要用px?
因为存在着很多不同屏幕密度的手机,屏幕密度是什么?就是dpi,就是单位长度里的像素数量。想象一下,如果这些手机的尺寸一样,屏幕密度相差很大,那么是不是说一个手机水平方向上像素很少,另一个手机水平方向上像素很多?那我们画同样pix数量的时候,它显示的长度不就会不一样了?比如下面图中的两个手机,同时设置2px长度的Button,在屏幕密度较高的手机里就会显示的比较小。而同时设置的2dip长度的Button,在两个手机上显示的大小是一样的。
图 5
所以如果你在App布局中都用的px作为单位,那么你的App跑在各个设备上就会出现奇奇怪怪的现象了。来看一下emulator上的效果,我定义了两个Button,分别用px和dip做单位。布局文件里这样写
<Button android:layout_width="100px" android:layout_height="100px" android:text="@string/str_button1"/> <Button android:layout_width="100dip" android:layout_height="100dip" android:text="@string/str_button1"/>
显示的界面是这样的:
图 6
getResources().getDisplayMetrics().densityDpi 就是屏幕密度。
getResources().getDisplayMetrics().density 也可以理解为1dip相当于多少个px啦。
上面的dpi是240,1dip=1.5px
你看,100dip的Button是100pxButton的1.5倍长吧。
参考文章:http://www.cnblogs.com/yaozhongxiao/archive/2014/07/14/3842908.html