天天看点

Day7.android适配之px、pt、dp、dip、dpi、sp的意义及区别

        px

                pixel,即像素,

1px

代表屏幕上的一个物理的像素点比如我们说的 1920x1080说的就是1920像素和1080像素。

        dpi

                dots per inch,每英寸的像素数,也就是屏幕密度,它的计算公式是:

Day7.android适配之px、pt、dp、dip、dpi、sp的意义及区别

,这里的长和宽指的是屏幕分辨率,比如一个1902x1080的5英寸手机,它的dpi就是:

Day7.android适配之px、pt、dp、dip、dpi、sp的意义及区别

 =440.5814340200 ,这个数值有什么意义呢?其实它对应着下面的dp(dip)与像素间的换算关系,对于Android手机来说,常见的dpi有如下几种:

  •     ldpi:dpi范围为0 ~ 120
  •     mdpi:dpi范围为120 ~ 160
  •     hdpi: dpi范围为160 ~ 240
  •     xhdpi:dpi范围为240~320
  •     xxhdpi:dpi范围为320~480

          在实际开发中,通常以dpi值120、160、240、320、480分别指代ldpi、mdpi、hdpi、xhdpi、xxhdpi。通常屏幕密度越大的手机显示的图像会越细腻。可以通过如下代码获取当前Android设备的屏幕密度:

private void getDpi() {
    DisplayMetrics dm = getResources().getDisplayMetrics();
    Log.i("TAG", "density = " + dm.density);
    Log.i("TAG", "densityDpi = " + dm.densityDpi);
}
           

          若我们在一台屏幕密度为320dpi的Android手机上运行以上代码,会得到如下输出:

density = 2
densityDpi = 320
           

          上面输出中的densityDpi就是Android手机屏幕的dpi值,那么density是什么呢?实际上它代表的是当前屏幕的dpi值与基准dpi值的比值,这个基准dpi值为160。

          现在我们已经理解了dpi,接下来让我们揭开dp的神秘面纱。

      dp(dip)

                   device independent pixel,即设备无关像素。之所以与设备无关,是因为它是通过与基准dpi的比例关系转化为要显示的像素点,比如上现的dpi是320,基准值是160,那么1dp=320/160*1=2px,同时我们也可以计算其它dpi下dp与px的关系:

  •     ldpi:dpi范围为0 ~ 120,1dp=0.75px
  •     mdpi:dpi范围为120 ~ 160,1dp=1px
  •     hdpi: dpi范围为160 ~ 240,1dp=1.5px
  •     xhdpi:dpi范围为240~320,1dp=2px;
  •     xxhdpi:dpi范围为320~480,1dp=3px           

      pt

              通常用来作为字体的尺寸单位,1 pt相当于1/72英寸。

      sp

             通常用于设置字体大小的单位,与dp类似,网上大部分博客都有说dp与sp对px的转化关系相同,那为什么还要对字体专门设置一个sp呢?显然它们还是有区别的:

             我们先来一起看下TypedValue类中包含的一个用户将dp、sp等单位转换为px的静态方法:

public static float applyDimension(int unit, float value,DisplayMetrics metrics) {
        switch (unit) {
        case COMPLEX_UNIT_PX:
            return value;
        case COMPLEX_UNIT_DIP:
            return value * metrics.density;
        case COMPLEX_UNIT_SP:
            return value * metrics.scaledDensity;
        case COMPLEX_UNIT_PT:
            return value * metrics.xdpi * (1.0f/72);
        case COMPLEX_UNIT_IN:
            return value * metrics.xdpi;
        case COMPLEX_UNIT_MM:
            return value * metrics.xdpi * (1.0f/25.4f);
        }
        return 0;
    }
           

               若要将sp转换为px,则会执行如下代码:

return value * metrics.scaledDensity;
           

               可以看到,sp转换为px的计算公式与dp转换为px时相似,那么scaledDensity是什么呢?实际上,scaledDensity不同于density,scaledDensity是可以动态改变的,当用户改变了Android设备的字体缩放比例时,scaledDensity的值就会发生变化。scaledDensity的计算公式为:scaledDensity = density * fontScale。其中fontScale代表用户设定的Android设备字体缩放比例,默认为1。也就是说,当用户没有改变Android设备的字体缩放比例时,sp、dp与px的换算是相同的。