为了账号安全,请及时绑定邮箱和手机立即绑定

深入理解dp,px,以及density

标签:
Android

notice: 首先记住我手机的配置. 

我的手机 小米M1 

分辨率为 480px * 854px

屏幕密度 240dpi

屏幕大小 4.0英寸


1。名词解释:

dpi :(Dots Per Inch),指每英寸的像素,是衡量打印机打印精度的主要参数之一。

ppi:PPI(Pixel Per Inch)表示数字影像的解析度 (也许这样太过于抽象,你可以这样理解 dpi 就是 ppi)

分辨率: 例如 480 * 854 就是说 我的屏幕宽度有 480个像素点 ,高度有 854个像素点。

屏幕大小: 例如我的是4.0 英寸, 就是指 从屏幕的左上角 到 屏幕的右下角 连线长度为4.0英寸(可以换成厘米)

px: 像素单位。最基础的图像构成元素单位。

dp: Android发明的长度单位,具体的下边会说。


2。原因解释:

我们为什么会产生分辨率和屏幕密度的困扰?


注意上图:对于一个 宽度为5px 的线,我们希望在不同的手机上表现效果像上面的图一样吗?

我是这样认为的,我们期望的效果并不是如上图那样的,我们希望5px的线在B屏幕上被缩放,和屏幕A中一样的比例。

如下图:



我们期望的,往往是这种效果,所以这条线在屏幕B上,不能是5px,但是具体是多少px呢? 现在我们是不知道的,不如我们来动手算算吧~各位是不是都跃跃欲试了?

我们设定,屏幕B中的线长度为 X px。 设定屏幕A总宽度为 At ,屏幕B总宽度为Bt。

So,我们来比一下吧!


所以,我们的X可以推导出来:


这样,我们就可以计算出,在B屏幕上,这条线要画多长,才可以维持比例。

现在我们来做一个疯狂的假设吧,来死狗。

屏幕A 为谷歌定义的标准屏幕,谷歌为了让图像在各个屏幕上显示的比例相同,程序会为我们自动计算B屏幕中线的长度。(用上述公式计算)

现在我们来反推一下,我们用别的手机(密度不同,可以认为是屏幕B),在屏幕上画一条线,这条线应该在谷歌标准的屏幕上占多长呢?


首先,我们必须明白一点: 一个屏幕,对于宽度,有两重含义。

一种宽度叫做像素宽度:即 横向排列的像素点一共有多少个。 例如 480 * 854的手机,我的像素宽度就为 480

一种宽度叫做物理宽度:即 我的手机横向到底有多少厘米。 我的手机是4.0英寸屏幕,高宽比是16:9,勾股定理求出,我的物理宽度是1.9英寸。

所以,上面的At,Bt 并不能用宽度来表示,我们必须用一个更加公平的量来表示,有点像物理学的密度。所以,上图中的At,Bt应该为两种屏幕的密度。屏幕密度的求法文章最后再讲述。


好的,看到这里,我们来转换一下上面的公式和假设。

由于屏幕A是谷歌规定的官方标准,所以我们可以查阅资料得知:

屏幕A的参数:

分辨率     320 * 480

屏幕密度 160

我们来计算一下,我们的手机(即屏幕B上)同样的线段,应该在屏幕A上展示的宽度为多少?

设我们的手机上,所要展示的宽度为Y,设在谷歌的屏幕需要展示的宽度为X,设A的屏幕密度(谷歌规定的密度)为Ad,设B的屏幕密度(不同于规定密度的设备)为Bd,公式如下:



文字总结一下上图,最终公式为 X =  Y(线段宽度) / (B屏幕密度 / A屏幕密度)

这样看是不是很眼熟? 对的!你没看错!X的单位就是谷歌规定的 dp!

所以X的单位就是dp!

公式也可以写成 

1.  dp =  px (线段宽度的单位) /  density

2.  density = Bd / Ad;

由于谷歌与规定,标准的dpi为160,所以最终公式就推导出来了!

dp = px / ( dpi / 160)

这个公式到底有什么意义呢?

好的,我这里就和大家做一个小计算。


我的手机信息dpi为240,宽度为480px,高度为854px.

所以,我的手机宽高各是多少dp呢?

带入上面红色的公式: 

宽度:dp = 480 / (240 / 160) = 320dp

高度:dp = 854/ (240 / 160) =  569.3333dp

我做了一个android的demo,一个ImageView宽设置为 320dp 高度为569dp,事实证明,显示的就是全屏幕,也就是以上理论完全正确!


假设有一款手机,屏幕分辨率720px * 1280px 屏幕密度是320。

宽度: dp = 720 / (320 / 160) = 360dp

高度: dp = 大家自己算算看?


也就是说 对于同一张图片,在密度不同的屏幕上,要展示的图片大小px是不同的。如果我们只使用一套图片,则会在不同的屏幕上进行拉伸和缩放。具体图片px和文件夹的关系我会在稍后的博客中写出。


不知道现在 开发者们有没有理解为什么我们写的时候要写成dp呢? 

因为写成dp可以自动适应不同屏幕密度的手机,但是dp不是万能的,原因很简单,每个手机的宽度(dp),高度(dp)都不一定是相同的。

简而言之就是说,对于一个宽度为320dp和360dp的两款手机,我们最好的方法就是让布局去自适应,而写死dp的值,可能会导致布局混乱。


这篇文章就写到这里了。如果有时间,我会写写android各种文件夹的原理,关于ldpi,hdpi等这些文件夹的原理。

文章最后附上屏幕密度如何计算。


dpi (屏幕密度)如何计算? 首先,要明白dpi的含义。dpi 指的就是 一英寸屏幕上 到底有多少个像素点。

所以公式为: dpi = 屏幕总px / 屏幕大小。


4.0是屏幕的大小,980是斜线的像素总数,所以我的手机dpi就为240.


以下是Java版的计算Dpi代码


[java] view plaincopy

  1. /** 

  2.  * E.g: 480*853分辨率,屏幕大小为4.0英寸  

  3.  * @param width 480 

  4.  * @param height 853 

  5.  * @param inch 4.0 

  6.  * @return dpi 

  7.  */  

  8. public static double calculateDpi(int width,int height,double inch){  

  9.     double diagonal = Math.sqrt(width * width + height * height);  

  10.     return diagonal / inch;  

原文链接:http://www.apkbus.com/blog-241057-58777.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消