欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中的常用尺寸单位(dp、sp)快速入门教程

程序员文章站 2023-11-12 17:58:34
常见尺寸单位 android开发中的常用尺寸单位有如下几种: dp (dip) px pt inch sp 算不知道确切含...

常见尺寸单位

android开发中的常用尺寸单位有如下几种:

  • dp (dip)
  • px
  • pt
  • inch
  • sp

算不知道确切含义,相信对于以上这几种尺寸单位大家也都比较脸熟,这里先让我们重新认识一下它们:

  • dp (dip): 即设备无关像素(device independent pixels),这种尺寸单位在不同设备上的物理大小相同。
  • px:即像素(pixel),这个不用多说。
  • pt:通常用来作为字体的尺寸单位,1 pt相当于1/72英寸。
  • inch:英寸,1 英寸约等于2.54厘米,主要用来描述手机屏幕的大小。
  • sp:大部分人只知道它通常用作字体的尺寸单位,实际大小还与具体设备上的用户设定有关。(如果你对"sp"的了解停留于此,那么看完这篇文章后你会更透彻的理解它^ _ ^)

在上面几种常见的尺寸单位,dp和sp可以看做是虚拟尺寸。其中dp是与设备无关的虚拟像素单位,开发者为ui控件指定以dp为单位的大小后,在不同屏幕密度的android设备上便能够具有相同的物理尺寸。dp的出现让开发者无需关注屏幕密度、物理像素之间的换算关系。sp则与dp相似,但它主要用作字体的尺寸单位,与dp的区别是:android系统支持用户设定字体大小,因而sp的实际大小还会根据用户设定在原基础上进行缩放。

下面来详细介绍dp与sp这两种尺寸单位。

尺寸单位详解之dp

dp的全称是device independent pixels,在具有不同屏幕密度的设备上,1 dp的物理大小是相同的。那么,什么是屏幕密度呢?

屏幕密度

手机的屏幕密度通常指的是手机屏幕的dpi(dots per inch),也就是每英寸的像素数。对于android手机来说,常见的dpi有如下几种:

  • ldpi:对应的dpi范围为0 ~ 120,也就是说每英寸有0到120个像素点的屏幕的屏幕密度都属于ldpi
  • 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

上面我们提到了选择dpi值160作为基准屏幕密度,这个基准屏幕密度人为建立起了dp与px间的关系:在dpi为160的android设备上,1 dp = 1px。假设x为某ui控件以px为单位的大小,y为同一ui控件以dp为单位的大小,densitydpi表示屏幕密度,则x与y的关系为:x = y * densitydpi / 160。

介绍完了dp,接下来让我们探究一下sp这个尺寸单位的真面目。

尺寸单位详解之sp

在介绍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;
 }

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

return value * metrics.density;

density我们在前面介绍过,指的是当前dpi与基准dpi(160)的比值。density的计算方式就是当前屏幕的dpi除以160。也就是说,在屏幕的dpi为120、160、320、480时,density的值分别为0.75、1、2、3。
若要将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的换算是相同的。

多分辨率之殇

市面上存在着的各种不同分辨率的android设备为广大android开发者挖了众多的坑,比如:

  • 需要为不同分辨率的android设备单独维护一套dimens文件;
  • 通常ui设计师只会针对某种特定分辨率的设备为我们标注ui控件的像素大小,相信不少小伙伴都受够了手动换算不同分辨率设备上ui控件像素大小的痛苦;
  • 通常我们需要为每种分辨率的android设备维护一个drawable文件夹以获得比较好的图片显示效果,这会导致apk文件尺寸的臃肿;而且若某个drawable文件夹下的图片需要修改,那么就需要替换其他所有drawable文件夹中对应的图片。如果不小心漏掉了某个drawable文件夹下的图片,则会导致该图片在某些分辨率的手机上失真。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。