px、dp和sp,这些单位有什么区别?
DP
这个是最常⽤但也最难理解的尺⼨单位。它与“像素密度”密切相关,所以
⾸先我们解释⼀下什么是像素密度。假设有⼀部⼿机,屏幕的物理尺⼨为1.5英⼨x2英⼨,屏幕分辨率为240x320,则我们可以计算出在这部⼿机的屏幕上,
每英⼨包含的像素点的数量为240/1.5=160dpi(横向)或320/2=160dpi(纵向),160dpi就是这部⼿机的像素密度,像素密度的单位dpi是Dots Per Inch的缩写,即每英⼨像素数量。
横向和纵向的这个值都是相同的,原因是⼤部分⼿机屏幕使⽤正⽅形的像素点。
不同的⼿机/平板可能具有不同的像素密度,例如同为4⼨⼿机,有480x320分辨率的也有800x480分辨率的,前者的像素密度就⽐较低。
Android系统定义了四种像素密度:低(120dpi)、中(160dpi)、⾼(240dpi)和超⾼(320dpi),它们对应的dp到px的系数分别为0.75、1、1.5和2,这个系数乘以dp长度就是像素数。
例如界⾯上有⼀个长度为“80dp”的图⽚,那么它在240dpi的⼿机上实际显⽰为80x1.5=120px,在320dpi的⼿机上实际显⽰为80x2=160px。
如果你拿这两部⼿机放在⼀起对⽐,会发现这个图⽚的物理尺⼨“差不多”,这就是使⽤dp作为单位的效果
px:
即像素,1px代表屏幕上⼀个物理的像素点;
px单位不被建议使⽤,因为同样100px的图⽚,在不同⼿机上显⽰的实际⼤⼩可能不同,如下图所⽰
dip:
Density independent pixels ,设备⽆关像素。
与dp完全相同,只是名字不同⽽已。在早期的Android版本⾥多使⽤dip,后来为了与sp统⼀就建议使⽤dp这个名字了。
⽐如⼀个机器,屏幕4⼨,分辨率480X800,他的dpi能算么。
因为不知道边长,肯定不能分开算,4是对⾓线长度,那直接⽤勾股定理算对⾓线像素,除以4,算出来⼤概是 dpi = 233 像素/英⼨。
那么density就是(233 px/inch)/(160 px/inch)=1.46 左右
顺带说下,android默认的只有3个dpi,low、medium和high,对应 120、160、240,如果没有特别设置,所有的dpi都会被算成这3个,具体可以参考下这个帖⼦
其中的default就是160。
sp:
与缩放⽆关的抽象像素(Scale-independent Pixel)。
sp和dp很类似但唯⼀的区别是,Android系统允许⽤户⾃定义⽂字尺⼨⼤⼩(⼩、正常、⼤、超⼤等等),当⽂字尺⼨是“正常”时
1sp=1dp=0.00625英⼨,⽽当⽂字尺⼨是“⼤”或“超⼤”时,1sp>1dp=0.00625英⼨。一般使用的分辨率的显示密度是多少dpi
类似我们在windows⾥调整字体尺⼨以后的效果——窗⼝⼤⼩不变,只有⽂字⼤⼩改变。
最佳实践,⽂字的尺⼨⼀律⽤sp单位,⾮⽂字的尺⼨⼀律使⽤dp单位。
例如textSize="16sp"、layout_width="60dp";偶尔需要使⽤px单位,例如需要在屏幕上画⼀条细的分隔线
像素转换
我们写布局的时候,肯定还是要知道1个dp到底有多少px的。
  换算公式如下: dp = (DPI/(160像素/英⼨))px = density px
  注意,这⾥都是带单位的。px是单位,dp是单位,density没单位。
  为了⽅便,假设dpi是240 像素/英⼨,那么density就是1.5
  那么就是 dp=1.5px ,注意这是带了单位的,也就是设备⽆关像素 = density 像素
  那么转换为数值计算的话,应该是下⾯这个式⼦
  PX = density * DP
也就是
  像素值 = density * 设备⽆关像素值,请注意这⾥有个值字。
为啥标准dpi = 160
  (1)Android Design [1] ⾥把主流设备的 dpi 归成了四个档次,120 dpi、160 dpi、240 dpi、320 dpi
  实际开发当中,我们经常需要对这⼏个尺⼨进⾏相互转换(⽐如先在某个分辨率下完成设计,然后缩放到其他尺⼨微调后输出),⼀般按照 dpi 之间的⽐例即 2:1.5:1:0.75   来给界⾯中的元素来进⾏尺⼨定义。
  也就是说如果以 160 dpi 作为基准的话,只要尺⼨的 DP 是 4 的公倍数,XHDPI 下乘以 2,HDPI 下乘以 1.5,LDPI 下乘以 0.75 即可满⾜所有尺⼨下都是整数 pixel 。
  但假设以 240 dpi 作为标准,那需要 DP 是 3 的公倍数,XHDPI 下乘以 1.333,MDPI 下乘以 0.666 ,LDPI 下除以 2
  ⽽以 LDPI 和 XHDPI 为基准就更复杂了,所以选择 160 dpi
(2)这个在Google的官⽅⽂档中有给出了解释,因为第⼀款Android设备(HTC的T-Mobile G1)是属于160dpi的。
为什么我们在布局的时候最好要⽤dip,不要⽤px?
 是因为这个世界上存在着很多不同屏幕密度的⼿机,屏幕密度是什么?就是dpi,就是单位长度⾥的像素数量。
  想象⼀下,如果这些⼿机的尺⼨⼀样,屏幕密度相差很⼤,那么是不是说⼀个⼿机⽔平⽅向上像素很少,另⼀个⼿机⽔平⽅向上像素很多?那我们画同样pix数量的时候,它显
  ⽰的长度不就会不⼀样了?
  ⽐如下⾯图中的两个⼿机,同时设置2px长度的Button,在屏幕密度较⾼的⼿机⾥就会显⽰的⽐较⼩。
  ⽽同时设置的2dip长度的Button,在两个⼿机上显⽰的⼤⼩是⼀样的。
所以如果你在App布局中都⽤的px作为单位,那么你的App跑在各个设备上就会出现奇奇怪怪的现象了。
  来看⼀下emulator上的效果,我定义了两个Button,分别⽤px和dip做单位。
  布局⽂件⾥这样写
<Button android:layout_width="100px"
android:layout_height="100px"
android:text="@string/str_button1"/>
<Button android:layout_width="100dip"
android:layout_height="100dip"
android:text="@string/str_button1"/>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。