说清楚px,dip和dp以及px和dp相互转换(一、)

Android 开发学习 专栏收录该内容
4 篇文章 0 订阅

在代码中编写需要使用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 是为了实现四舍五入的)

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页

打赏

米封

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值