在代码中编写需要使用px,在布局文件中需要使用dp(dip),这中间还有一个dip,这里说明一下.
我们使用手机一般说一个屏幕分辨率,一般是用手机纵向分辨率x手机横向分辨率表示的.
比如nexus 6p,2560x1440像素,表示纵向2560个像素,横向1440个像素.
手机尺寸一般是说手机斜对角线的长度,nexus 6p 是5.7英寸,大概是5.7*2.54=14.478cm(1英寸=2.54cm)
px:像素:构成图像的最小单位.
dpi:屏幕像素密度,指每英寸上的像素点数,dot per inch的缩写,与屏幕尺寸和屏幕分辨率有关.
dpi的计算呢,就是计算:斜对角线的像素数/斜对角线的长度=dpi(屏幕像素密度)
但是实际上我们需要dpi时候还要知道手机的斜对角长度?这不扯淡吗?当然是扯淡,我们知道这个值是这么来的就行了,我们不用计算这些乱七八糟的东西,实际上Android里面早就写好了这个值,我们直接获取就好了.
float selfDpi=Resources.getSystem().getDisplayMetrics().densityDpi;//本机的dpi
以上的基本的了解知识,有了上面的了解,我们来反推px和dp怎么相互转化.
首先,屏幕为240*320的手机屏幕,其尺寸就是1.5英寸乘2英寸的屏幕. 它的dpi就为160dpi,所以在这个手机上dp和px的长度是相等的,这是Android提供的一个对照基准。而在240dpi设备上1dp=1.5px,所以说这个对照关系就是
本机dpi/160dpi=px/dp
px=(本机dpi*dp)/160dpi
dp=(px*160dpi)/本机dpi
到这里就是明白怎么转换了.
public static int myDpToPx(float dp) {
//px=(本机dpi*dp)/160dpi
return (int) (dp *selfDpi/160 + 0.5);
}
public static int myPxToDp(float pix) {
//dp=(px*160dpi)/本机dpi
return (int) (160 * pix/selfDpi + 0.5);
}
我们觉得每次还要乘以或者除以160好烦呀,Android 里面也帮我们算好了比率.
float density=Resources.getSystem().getDisplayMetrics().density;
float scale=Resources.getSystem().getDisplayMetrics().densityDpi/160;
上面这两个值,其实是相等的,我们就不需要计算160了.
所以呢,
public static int myDpToPx(float dp) {
//px=(本机dpi*dp)/160dpi
return (int) (dp *destiny + 0.5);
}
public static int myPxToDp(float pix) {
//dp=(px*160dpi)/本机dpi
return (int) (pix/destiny + 0.5);
}
类文件如下:
public class ViewUtils {
public static int widthDp;//本机横向的最大dp值
public static int heightDp;//本机纵向最大dp值
public static int selfDpi;//本机的dpi
public static float widthPx;//本机横向宽度像素值
public static float heightPx;//本机纵向高度像素值
static {
selfDpi = Resources.getSystem().getDisplayMetrics().densityDpi;
widthPx = Resources.getSystem().getDisplayMetrics().widthPixels;
heightPx = Resources.getSystem().getDisplayMetrics().heightPixels;
widthDp = myPxToDp(widthPx);
heightDp = myPxToDp(heightPx);
}
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;//density: selfselfDpi/16
return (int) (dipValue * scale + 0.5f);
}
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
public static int myDpToPx(float dp) {
//本机dpi/160=px/dp
return (int) (dp * selfDpi / 160 + 0.5);
}
public static int myPxToDp(float pix) {
return (int) (160 * pix / selfDpi + 0.5);//pxValue / scale
}
}
(最后的0.5 是为了实现四舍五入的)