博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
转 Android:sp与dp(densityDpi与scaledDensity)
阅读量:5207 次
发布时间:2019-06-14

本文共 3250 字,大约阅读时间需要 10 分钟。

一般在布局上设置控件大小维度的单位采用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的值

[java] 
 
  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()获取。

 

[java] 
 
  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.   
  6. ((TextView) this.findViewById(R.id.label)).setText(result);  
  7. ((TextView) this.findViewById(R.id.sp)).setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);  
  8. ((TextView) this.findViewById(R.id.dp)).setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24);  

 

转载于:https://www.cnblogs.com/wikiki/p/4323762.html

你可能感兴趣的文章
CodeForces - 878A Short Program(位运算)
查看>>
Mysql聚簇索引和非聚簇索引
查看>>
Hive入门之UDFS函数
查看>>
python文件操作笔记
查看>>
泛型委托
查看>>
笔试题拾遗
查看>>
与虚拟机Oracle连接出现ora-12154问题的解决
查看>>
JavaScript对象(一)
查看>>
Sublime View In Browser
查看>>
linux下可执行程序如何定位共享库文件以及如何让系统找到用户指定的库
查看>>
FPGA机器学习之机器学习的n中算法总结1
查看>>
Bootstrap的js插件之轮播(carousel)
查看>>
linux自旋锁
查看>>
路冉的JavaScript学习笔记-2015年1月23日
查看>>
IPTABLES详解
查看>>
Linux 下tomcat 的重新启动
查看>>
利用node js 来创建一个服务器
查看>>
objectiveC【语法】修饰符 static extern const
查看>>
史上最全的maven pom.xml文件教程详解
查看>>
ubuntu装软件包
查看>>