dp的定义原理和dpi,ppi,px,sp之间的区别

扩展知识:
1080p和720p是什么意思
百度百科分辨率中最后一段话不明白的,可以参考这里


在开始讲解dp前,先来认识一些概念:

相关尺寸单位

px(pixel 像素):屏幕上的点,一般HVGA代表320x480像素

in(inch 英寸):长度单位: 英寸

1英寸(in)=2.54厘米(cm)

分辨率

“分辨率”被表示成每一个方向上的像素数量,比如640X480等。某些情况下也可以同时表示成“每英寸像素”(ppi)以及图形的长度和宽度。比如72ppi,和8X6英寸。

描述分辨率的单位有:(dpi点每英寸)和ppi(像素每英寸)。(PPI和DPI都是分辨率。PPI用于显示器,一个像素一个格子。DPI用于打印机,“每英寸墨点”)

    • - ppi(pixels per inch):单位英寸上的像素数量,是物体的属性。公式为: ppi = 屏幕对角线像素数(px) / 屏幕对角线长度(in)

    • - dpi(dots per inch):单位英寸上的像素数量,是单位。公式为: dpi = 屏幕对角线像素数(px) / 屏幕对角线长度(in)。

    • ppidpi经常会出现混用现象。它们都是用来描述屏幕的属性。从技术角度说,“像素”(P)只存在于计算机显示领域,而“点”(d)只出现于打印或印刷领域。

      描述手机屏幕属性使用ppi,在开发过程中drawable 各个文件对应的是dpi。这两个单位的计算方法一样,描述不一样,只是因为使用的场景不一样


      QVGA : 分辨率为 320*240 (Quarter VGA即四分之一)
      HVGA :分辨率为 320*480 ( Half-size VGA即一半)
      VGA : 分辨率为 640*480 (全称Video Graphic Array)
      WVGA : 分辨率为 800*480 (Wide VGA 很多网页的宽度都是800,所以WVGA的手机屏幕会更加适合于浏览网页)
      FWVGA :分辨率为 854*480 手机c8813

      英寸是一个物理单位,大家平常说的手机屏幕4.3英寸,4.5英寸指的是屏幕对角线的长度,如下图所示:

      这里写图片描述

      分辨率480 x 800,屏幕尺寸4.3英寸和分辨率540 x 960,屏幕尺寸4.5英寸的DPI分别是:
      这里写图片描述

      与分辨率无关的度量单位

      Android支持下列所有单位:

      • dp(dip : device independent pixels(设备独立像素)):一种基于屏幕密度抽象长度单位。在每英寸160点的显示器上,1dp = 1px。(注意和上面介绍的dpi区分)

      • sp(与刻度无关的像素):与dp类似,但是可以根据用户的字体大小首选项进行缩放。



      下面通过几个问题,来让你深入了解dp的定义和

      一、为什么规定160dpi规格的显示器上,1dp = 1px?

      答:这个在Google的官方文档中有给出了解释,因为第一款Android设备(HTC的T-Mobile G1)是属于160dpi的。

      为什么说是属于160dpi?
      T-Mobile G1的DPI,其实它准确的PPI不等于160,G1的配置信息如下:

      屏幕尺寸:3.2 寸(8.1 厘米)
      分辨率:320 x 480(HVGA)

      如果按照上面的计算方式,T-Mobile G1应该属于180dpi,使用计算器,计算结果为180.277564dpi。

      为什么不直接用180作为基准(mdpi)而是160呢?

      180上下不好做适配,但是160无论是乘以0.5/2/1.5都很好适配,这就是为什么是属于而不是等于。

      为什么要选一个160dpi作为标准呢?

      Android其实为了不至于为每一个设备制造商做适配(其实资源文件的分包就算适配了:drawable-hdpi,drawable-ldpi),将不同屏幕大小和不同dpi的设备大致划分为四类,如下图:
      这里写图片描述

      大家可以看到T-Mobile G1的参数属于mdpi区域的,以上就是取160dpi作为基准的原因。
      在编程过程中获得的density,与自己手动计算出来的dpi是不一样的,因为这里进行了分类,所以不同dpi设备上,比例缩放有一点点差异,详见下面第三点


      二、dp

      如果有兴趣可以看一下这个类的源码(网址):GrepCode: android.util.DisplayMetrics (.java) ,这个类中有很详细的dpi相关的成员函数和变量,下面的代码是在开发时获取dpi的代码,

      DisplayMetrics metrics = new DisplayMetrics();
      getWindowManager().getDefaultDisplay().getMetrics(metrics);
      iDensity = (int)( metrics.density * 160 );
       
       
      • 1
      • 2
      • 3

      2.1、为什么要引入dp?

      答:dp实际是dip(density independent pixel),独立密度像素,意思就是与density密度(dpi)无关。
      我使用dp作为单位设置控件,不管你什么屏幕大小,多大的dpi,显示的效果始终保持一致。

      举例:

      不使用dp,使用px的效果

      1. 假如我们不引入dp,还是使用原始的px,现在我们需要在手机屏幕上绘制一条直线,在160dpi(每英寸160个像素点),宽度是1英寸的手机上,我们设置这条直线长度是160px(占据160个像素点),也就是直线长度正好是手机的宽度
      2. 但是240dpi(一英寸240个像素点),宽度是1英寸的手机上安装了这个app,长度只有屏幕宽度的2/3

      类似于下面这样的效果:
      这里写图片描述

      使用dp的效果

      • 上面这张图来自Google的开发网站。如果引入dp这个单位,这种问题就不会发生了,还是以上面的例子说明,如果在160dpi的设备上使用的是160dp,无论移植到240,120dpi上显示效果都是一致的。效果如下图:
        这里写图片描述

      为了使用户界面能够在现在和将来的显示器类型上正常显示,建议大家始终使用sp作为文字大小的单位,将dp(即dip)作为其他元素的单位。当然,也可以考虑使用矢量图形,而不是用位图。


      2.3、px和dp的换算公式

      px和dp的换算公式:px = dp * (dpi / 160)


      dp: dp也就是dip:device independent pixels(设备独立像素)
      dp是一种与密度无关的像素单位,在每英寸160点的屏幕上,1dp = 1px

      不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素

      <Button android:layout_width="wrap_content"   
          android:layout_height="wrap_content"   
          android:text="@string/clickme"  
          android:layout_marginTop="20dp" />  
       
       
      • 1
      • 2
      • 3
      • 4

      sp: scaled pixels(刻度像素). 主要用于定义字体的大小,而从来不再layout上使用

      <TextView android:layout_width="match_parent"   
          android:layout_height="wrap_content"   
          android:textSize="20sp" />  
       
       
      • 1
      • 2
      • 3

      px:pixels(像素). 不同设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多


      三、为什么手工计算dp对应的px大小与实际显示的px不一样

      1、实际不同的手机上控件的大小和屏幕比例感觉都差不多,因为Android把屏幕大小,像素密度等接近的归为一类dpi,所以实际显示的px和手工计算出来的px尺寸有一定差异。

      由于Android的划分,使用dp为长度单位,导致计算出来的px与实际显示px不符合

      设备一:Sony Z2 屏幕尺寸:5.2in 屏幕分辨率:1080*1920 DPI:424
      设备二:华为 Mate 7 屏幕尺寸:6.0in 屏幕分辨率:1080*1920 DPI:367

      套用公式:px = dp * (dpi / 160),开发人员写一个高度为48dp的控件。

      在Sony Z2上的渲染像素为:48*424/160=127.2px
      在华为 Mate 7上的渲染像素为:48*367/160=110.1px
      这显然很荒谬:
      1.出现小数的像素个数,而像素的最小单位是1,在设备上无法显示。
      2.根据实际截图测试,Sony Z2实际渲染像素为144px(@3x),华为 Mate 7 实际渲染像素为144px(@3x)。

      也就是说,实际的渲染像素并不是按照此公式计算的。而是按照渲染倍率(即@2x,@3x)来计算的。
      实际的渲染像素如下:

      在Sony Z2上实际渲染像素为:48@3x=144px
      在华为 Mate 7上实际的渲染像素为:48@3x=144px


      原因:

      (density:n. 密度

      手机a的density = 手机a的ppi/160)

      以160ppi为基准,160ppi对应的density是1.0(mdpi),240ppi对应的density是1.5(hdpi),320ppi对应的density是2.0(xhdpi)…
      最关键的一点是,真机屏幕的ppi会取和以上标准最相近的标准ppi!然后density按照最相近的ppi来定。

      限定符说明比例
      ldpi适用于低密度 (ldpi) 屏幕 (0dpi~120dpi) 的资源。1dp=3/4px
      mdpi适用于中密度 (mdpi) 屏幕 (120dpi~160dpi) 的资源。(这是基线 密度。)1dp = 1px
      hdpi适用于高密度 (hdpi) 屏幕 (160dpi~240dpi) 的资源。1dp = 1.5px
      xhdpi适用于超高密度 (xhdpi) 屏幕 (240dpi~320dpi) 的资源。1dp = 2px
      xxhdpi适用于超超高密度 (xxhdpi) 屏幕 (320dpi~480dpi) 的资源。1dp = 3px
      xxxhdpi适用于超超超高密度 (xxxhdpi) 屏幕 (480dpi~640dpi) 的资源。1dp = 4px

      2、这是一个假设、使用手动计算出的dpi(通过公式dpi = 屏幕对角线像素数(px) / 屏幕对角线长度(in)),相同dp在不同手机显示的都是相同物理尺寸,而不是相同的屏幕占比。

      px和dp的换算公式:px = dp * (dpi / 160)

      px = dp * (dpi / 160) = dp * (px(屏幕对角线像素) / in(屏幕尺寸) / 160)

      因此在dp不变,in不变时,屏幕对角线像素数量越大,控件的px越大

      下面举个例子:

      手机类型屏幕对角线像素个数屏幕尺寸dpi160dp显示的像素个数160dp显示的英寸160dp在屏幕对角线的占比
      手机A480px3in160dpi160个1in1/3
      手机B640px2in320dpi320个1in1/2
      手机C960px3in320dpi320个1in1/3

      即使使用dp,也不能保证理论上,所有手机都能完美适配.

      本质上是规定了160dp等于1in,但是谷歌内部对手机进行了很好的dpi划分,所以使用dp才成为一种解决手机适配的方法,你可以多拿几款手机进行验证

      那为什么使用dp作为长度单位,可行呢?

      1. 有可能是在手机发展的道路中,不会出现手机A到手机B的情况,就算有估计也不会出现这么大的反差(屏幕缩小1/3,分辨率增加1/2),

      2. 还有就是我估计手机厂商内置已经设置好了dpi的值,谷歌在划分屏幕的归类时,也已经处理好这些问题了,关于如何划分手机对应的dpi,请参考这里

      本质上是规定了160dp等于1in,但是谷歌内部对手机进行了很好的dpi划分,所以使用dp才成为一种解决手机适配的方法

      总结:dp也就是dip。这个和sp基本类似。如果设置表示长度、高度等属性时可以使用dp或sp。但如果设置字体,需要使用sp。dp是与密度无关,sp除了与密度无关外,还与scale无关。

      如果屏幕密度为160,这时dp和sp和px是一样的。1dp=1sp=1px,但如果使用px作单位,如果屏幕大小不变(假设还是3.2寸),而屏幕密度变成了320。那么原来TextView的宽度设成100px,在密度为320的3.2寸屏幕里看要比在密度为160的3.2寸屏幕上看短了一半。

      但如果设置成100dp或100sp的话。系统会自动将width属性值设置成200px的。也就是100 * 320 / 160。其中320 / 160可称为密度比例因子。也就是说,如果使用dp和sp,系统会根据屏幕密度的变化自动进行转换.

      px 和 dp 互转换代码

      package com.hujl.util;
      import android.content.Context;  
      
      public class DensityUtil {  
      
          /** 
           * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 
           */  
          public static int dip2px(Context context, float dpValue) {  
              final float scale = context.getResources().getDisplayMetrics().density;  
              //因为有的dpi为160的1.5倍,所以计算完后,为了没有小数,加0.5
              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);  
          }  
      }  
       
       
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22

      参考:

      http://www.zhihu.com/question/33312136
      http://www.zhihu.com/question/20697111

    • 0
      点赞
    • 1
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    在移动应用开发中,设计尺寸是非常重要的。以下是一些常见的设计尺寸及其解释: 1. px(Pixel):像素。在计算机图形学中,像素是构成图像的基本单位,是一个矩形区域的最小单元。 2. pt(Point):点。在 iOS 设备上,1pt = 1/72 英寸。在 Android 设备上,1pt = 1/160 英寸。在设计师眼中,pt 是一个抽象的单位,不同的设备有不同的像素密度,但 pt 的大小在不同设备上是相同的。 3. ppi(Pixels Per Inch):每英寸像素数。ppi 越高,屏幕显示的图像越清晰。例如,iPhone 11 的 ppi 是 326,而 iPhone 11 Pro Max 的 ppi 是 458。 4. dpi(Dots Per Inch):每英寸点数。dpi 是印刷行业常用的单位,但在移动设备上也有用处,因为移动设备的屏幕本质上也是一种印刷技术。dpippi 的概念相似,但 dpi 通常用于打印机和扫描仪等设备。 5. dp(Density-independent Pixel):密度无关像素。dp 是 Android 设备上的一个单位,它与 pt 的概念类似,但是 dp 进行了像素密度的换算。例如,当设备像素密度为 160dpi 时,1dp = 1px;当设备像素密度为 320dpi 时,1dp = 2px。 6. sp(Scaled Pixels):可缩放像素。sp 是 Android 设备上用于字体大小的一个单位,它与 dp 的概念类似,但是 sp 进行了字体的缩放。例如,当设备像素密度为 160dpi 时,1sp = 1dp;当设备像素密度为 320dpi 时,1sp = 2dp。 在设计移动应用时,需要考虑不同设备的像素密度和屏幕尺寸。使用像素密度无关的单位(如 dpsp)能够确保设计在不同设备上的显示效果相同。

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值