一般在布局上设置控件大小维度的单位采用dp,而定义字体大小的单位采用sp。

dp是dip,density independent pixel,即密度无关的像素单位,说白了,就是这个维度相对于不同屏幕的显示效果一致。

在Android系统中定义的dp,sp单位都是为了解决Android设备不同屏幕的差异而进行的封装,物理上的屏幕仍然是基于像素的。

如果在运行的手机上截屏下来到手机上看,不管在手机还是平板上,如果分辨率相同,截屏后的图片分辨率就是一样的,如果是相同的应用界面,理论上截屏后的图片效果应该基本一致。

关于dp:

在屏幕上显示任何控件,图片,文字,最终都必须转化为像素单位进行绘制,因为屏幕驱动最终是以像素为单位进行绘制的(行扫描,或整屏幕,取决于驱动)。

举例来说:

如果一个800x1600的密度为320的手机上显示一个100x100的像素的Button,并且左右居中。

同时,在同样的分辨率的,密度为160的平板上显示该Button,并且左右剧中。

我们同时拿着这2个设备去看这个界面的时候,应该需要达到整体位置,比例都一致的感觉。

在手机上因为密度是320,我们应该是显示50dpx50dp的Button控件,在运行时会换算为100px *100px的尺寸,可以达到我们的UI效果。

在平板上为了达到相同的效果,我们希望在程序设计时定义的尺寸dp,在运行时应该能换算为100px * 100px, 由于它的密度是160,那么我们应该设置为100dpx100dp。

从这里可以看出来,为了应对同样的UI效果,实际上,我们需要设置不同的dp值,这个跟dp的目标并不冲突。因为UI做图的时候,肯定是基于一个屏幕分辨率,如1920x1080,但设备的物理尺寸他们往往不是很关心,也就是密度他们不太关心,他们希望一个整体协调的感觉(手机和平板)。

上述的情况,我们体现在 res/layout 平板和手机采用相同的layout 但是尺寸大小由 res/values/dimen.xml来定义。

values下针对 xhdpi(320密度,手机)和large-mdpi(160密度,平板)应该定义不同的尺寸(dp为单位),如上。

上述阐述,基于分辨率相同或基本一致,密度不同的情况。

现在看另外一种情况,同样的图片100px X 100px,我们希望在不同分辨率的手机上,相似的密度情况下都能友好的显示出UI的预期效果,也就是屏幕占比。

我们需要根据现在的情况,如果现在UI制作的时候是在800x1600的分辨率上做UI控件示意图,并且观察手机效果的时候是放在密度为320的手机上进行确认的。

那么就是 320的密度,我们定义为50dp x 50dp。 这个Button控件,我们希望在密度接近(如都是xhdpi)不同的分辨率的手机上都能正常且反应UI预期的显示,那么我们在xhdpi的dimen定义都是采用50dp x 50dp即可,这样根据dp与px的关系自然能较好的得到其px值,匹配UI效果(即便分辨率差别很大,我们可以简单想象分辨率翻倍的情况,极端点说,一个是另外一个的放大版本,但整体效果一致,dp值相同,但是实际控件占用的像素则不同)。

这个时候我们一般需要调整原始资源的大小(像素)以得到合适的屏幕占比。

上述阐述,基于密度基本一致,分辨率不同的情况,即定义在同样的dimen下。

有了上面的基础,我们对于不同的分辨率,不同的物理尺寸,密度就可以综合来设计尺寸了。

1.根据UI的示意图效果,假定分辨率相同,密度不同的情况,定义不同的dimen文件。

2.假设密度相同,分辨率不同的情况(一般需要更改原始图片大小,或9.png自适应)。

TypedValue类中:就是计算得到最终的px的值

  1. /**
  2. * Converts an unpacked complex data value holding a dimension to its final floating
  3. * point value. The two parameters <var>unit</var> and <var>value</var>
  4. * are as in {@link #TYPE_DIMENSION}.
  5. *
  6. * @param unit The unit to convert from.
  7. * @param value The value to apply the unit to.
  8. * @param metrics Current display metrics to use in the conversion --
  9. *                supplies display density and scaling information.
  10. *
  11. * @return The complex floating point value multiplied by the appropriate
  12. * metrics depending on its unit.
  13. */
  14. public static float applyDimension(int unit, float value,
  15. DisplayMetrics metrics)
  16. {
  17. switch (unit) {
  18. case COMPLEX_UNIT_PX:
  19. return value;
  20. case COMPLEX_UNIT_DIP:
  21. return value * metrics.density;
  22. case COMPLEX_UNIT_SP:
  23. return value * metrics.scaledDensity;
  24. case COMPLEX_UNIT_PT:
  25. return value * metrics.xdpi * (1.0f/72);
  26. case COMPLEX_UNIT_IN:
  27. return value * metrics.xdpi;
  28. case COMPLEX_UNIT_MM:
  29. return value * metrics.xdpi * (1.0f/25.4f);
  30. }
  31. return 0;
  32. }

关于sp:

为了将字体更好的在不同的设备间很好的显示,修改原理跟dp上述基本一样,只是文字基本是矢量的,只要设置尺寸即可,不需要重新制作资源。

Scale-independent Pixels - 一般情况下(不修改系统字体大小),sp和dp是一个值。

如果修改了系统字体大小,sp和dp就不同了。注意要用getResources()获取。

  1. DisplayMetrics metrics = getResources().getDisplayMetrics();
  2. String result = "\n"
  3. + "density : " + metrics.density + " (24 dp = " + 24 * metrics.density + " px)\n"
  4. + "scaledDensity: " + metrics.scaledDensity + " (24 sp = " + 24 * metrics.scaledDensity + " px)\n" ;
  5. ((TextView) this.findViewById(R.id.label)).setText(result);
  6. ((TextView) this.findViewById(R.id.sp)).setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);
  7. ((TextView) this.findViewById(R.id.dp)).setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24);

转 Android:sp与dp(densityDpi与scaledDensity)的更多相关文章

  1. Android px、dp、sp之间相互转换 系统默认12 sp

    px  就是像素 sp=dpX字体比例(1.25f) 一.dp(或者dip device independent pixels) 一种基于屏幕密度的抽象单位.在每英寸160点的显示器上,1dp=1px ...

  2. Android中dip, dp, px,pt, sp之间的区别:

    Android中dip.dp.sp.pt和px的区别   1.概述 过去,程序员通常以像素为单位设计计算机用户界面.例如:图片大小为80×32像素.这样处理的问题在于,如果在一个每英寸点数(dpi)更 ...

  3. Android px、dp、sp之间相互转换

    dp(dip): device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA.HVGA和QVGA 推荐使用这个,不依赖 ...

  4. Android px、dp和sp单位区别

    [转]http://www.cnblogs.com/bjzhanghao/archive/2012/11/06/2757300.html 在调整布局的时候,某些控件的大小需要设置单位: px: 即像素 ...

  5. 屏幕适配基础——了解:ppi、dpi、px、sp、dp

    做android开发绕不开的几个名词:ppi.dpi.px.sp.dp.那么它们的定义.区别和联系都是什么呢?这篇博客系统的做一个概述和总结. 1.基本概念 px:pixel,像素,电子屏幕上组成一幅 ...

  6. [Android] 字体使用dp单位避免设置系统字体大小对排版的影响

    [Android] 字体使用dp单位避免设置系统字体大小对排版的影响 以魄族mx3为例,在设置->显示->字体大小中能够选择字号大小例如以下图: 图1. 魄族mx3 会导致软件在有固定定高 ...

  7. Android开发中dp、dpi、px的区别(转)

    一.基本概念 - dp:安卓中的相对大小 - dpi:(dot per inch)每英寸像素多少 - px:像素点 二.详细说明 1.px和dpi - px: 平常所说的1920×1080只是像素数量 ...

  8. 字体使用sp、dp的区别

    Android设置字体大小, 该用sp还是dp? 大部分人肯定脱口而出, 用sp啊, 傻瓜都知道要用sp而不是dp!!! 那么为什么呢? 可能有人会说, 是google官方专门定义了sp这个单位来描述 ...

  9. 【转】Android中dip(dp)与px之间单位转换

    Android中dip(dp)与px之间单位转换 dp这个单位可能对web开发的人比较陌生,因为一般都是使用px(像素)但是,现在在开始android应用和游戏后,基本上都转换成用dp作用为单位了,因 ...

随机推荐

  1. grub4dos新手指南-2

    Grub4dos 新手指南 一.GRUB4DOS的配置文件Grub4dos 有三个文件,grldr.grldr.mbr和menu.lst,配置文件是menu.lst,和GRUB一样.该文件一般放在和启 ...

  2. 《JavaScript高级程序设计》读书笔记 ---语句

    do-while语句do-while 语句是一种后测试循环语句,即只有在循环体中的代码执行之后,才会测试出口条件.换句话说,在对条件表达式求值之前,循环体内的代码至少会被执行一次.以下是do-whil ...

  3. java 图片高保真缩放

    public class NarrowImage { /**     * @param im     *            原始图像     * @param resizeTimes     *  ...

  4. Python识别网站验证码

    http://drops.wooyun.org/tips/6313 Python识别网站验证码 Manning · 2015/05/28 10:57 0x00 识别涉及技术 验证码识别涉及很多方面的内 ...

  5. 怎么利用GitHub

    我们一直用GitHub作为 免费的远程仓库,如果是个人的开源项目,放到GitHub上完全没有问题,其实GitHub就是一个开源协作社区,既可以让 别人参与你的开源项目,也可以参与别人的开源项目,在Gi ...

  6. GitHub这么火,程序员你不学学吗? 超简单入门教程 【转载】

    本GitHub教程旨在能够帮助大家快速入门学习使用GitHub. 本文章由做全栈攻城狮-写代码也要读书,爱全栈,更爱生活.原创.如有转载,请注明出处. GitHub是什么? GitHub首先是个分布式 ...

  7. Docker学习笔记 — Docker私有仓库搭建【转载】

    标签: Docker 2015-03-10 21:08 24190人阅读 评论(0) 收藏 举报  分类: Docker(26)    目录(?)[+]   和Mavan的管理一样,Dockers不仅 ...

  8. mysql开启/关闭 update delete 安全模式

    在使用mysql执行update的时候,如果不是用主键当where语句,会报如下错误,使用主键用于where语句中正常. 异常内容:Error Code: 1175. You are using sa ...

  9. linq中first() firstordefault() last() lastOrDefault() single() singleOrDeafult

    一.firstordefault() 和 first() class Program { static void Main(string[] args) { List<Emp> list ...

  10. servlet多次跳转报IllegalStateException异常

    当发生在如下错误的时候,有一个方案可行, "java.lang.IllegalStateException: Cannot forward after response has been c ...