android中dp和px的关系

关于android的dp和px的关系是我刚开始学习android的第一个知识点,不知不觉学安卓也有一年了,但是偶然间我发现我理解的dp和px的关系一直是错的,真的是有一点搞笑,今天特意写一篇博客纪念一下这个我理解错一年的知识点。
dp和px之间又有一个dpi作为桥梁,我们分别看看这三个属性:

  • px:像素点,比如1080*1920的屏幕,就是宽1080个像素点和高1920个像素点。
  • ppi: 像素密度,这个概念挺好理解的就是屏幕每英寸的像素数量,关于他的计算方法(以1080 * 1920的5英寸屏幕为例):屏幕的对角线像素数/屏幕的尺寸 √(1080 * 1080+1920 * 1920)/5=441ppi。这也就意味着即使是相同分辨率的手机尺寸不同ppi也会改变。
  • dpi:dpi和ppi很容易搞混,其实他们是完全不同的两个东西,ppi有专门的公式计算,但是dpi没有,它往往是写在系统出厂配置文件的一个固定值,Android在规范中规定了不同的分辨率对应的dpi值,一般有120、160、240、320、480几个。比如,几部相同分辨率不同尺寸的手机的ppi可能分别是是430,440,450,那么在Android系统中,可能dpi会全部指定为480,该分辨率下1dp=3px。
  • dp(也叫dip)设备无关像素。关于dp的官方叙述为当屏幕每英寸有160个像素时(也就是160dpi),dp与px等价的,1dp=1px。那么当屏幕为240dpi时,1dp=(240/160)px=1.5px。也就是说dp和px的换算在于dpi这个值,计算的公式为:1dp=(屏幕的dpi/160)px。

关于dp和px的概念就这么多,还是很简单的(我这是在打脸吗),下面讲一下衍生出的几个问题:
1.系统根据dp计算像素值的过程
px = dp(dpi/160),这个不难理解,如果一个20dp的Button,在dpi为480的设备占的像素值就是20(480/160)=60px,这个有一点要注意,px的计算完全依照dpi这个参数,而不同尺寸和分辨率的机型的dpi可能相同,这就会造成显示差异。
2.手机屏幕dp最大值是多少?
这个是根据手机的像素数和dpi计算得到,公式:dp=px/(dpi/160)
例如一个1080*1920的手机,他的宽度有1080个像素点,dpi为480,根据公式可得:1080/(480/160)=360dp
同理长度:1920/(440/160)=640dp

3.dp和px的互相转换?
这里会用到我们在代码中可以获取到的一个值:手机密度Density,其实他就是手机的像素密度与基准的比值。 即像素密度为160时Density为1,可以通过下面的方法获取这个值:

float scale = context.getResources().getDisplayMetrics().density;

dp值转换为px值得方法为:
假设手机密度 :density = x,dp的值为y
由1dp = density px
可知ydp = yx px
所以结果为yx

px值转换为dp值得方法为:
假设手机密度 :density = x,px的值为y
由1px = 1/density dp
可知 ypx = y/x dp
所以结果为y/x

public class DensityUtil {  
  
    /** 
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 
     */  
    public static int dip2px(Context context, float dpValue) {  
        final float scale = context.getResources().getDisplayMetrics().density;  
        return (int) (dpValue * scale + 0.5f);  
    }  
  
    /** 
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp 
     */  
    public static int px2dip(Context context, float pxValue) {  
        final float scale = context.getResources().getDisplayMetrics().density;  
        return (int) (pxValue / scale + 0.5f);  
    }  
}  

至于为什么要加0.5f?
因为在java中,强制转换符把float转换为int时,是直接丢掉小数部分的,加0.5f起到了四舍五入的作用,可以减小误差。

  • 11
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值