博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TypedValue.applyDimension 中dp和sp之间转化的真相
阅读量:6503 次
发布时间:2019-06-24

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

   最近在看了许多关于dp-px,px-dp,sp-px,px-sp之间转化的博文,过去我比较常用的方式是:

1 //转换dip为px  2 public static int convertDipOrPx(Context context, int dip) {  3     float scale = context.getResources().getDisplayMetrics().density;  4     return (int)(dip*scale + 0.5f*(dip>=0?1:-1));  5 }  6   7 //转换px为dip  8 public static int convertPxOrDip(Context context, int px) {  9     float scale = context.getResources().getDisplayMetrics().density; 10     return (int)(px/scale + 0.5f*(px>=0?1:-1)); 11 }

然后看到了一种新的转化方式,代码如下:

1 public static int dp2sp(float dpVal){2     return (int)(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal,3             MyAppliction.getInstance().getApplicationContext().getResources().getDisplayMetrics()));4 }5  //?????6 public static int sp2dp(float spVal){7     return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal,8             MyAppliction.getInstance().getApplicationContext().getResources().getDisplayMetrics()));9 }

码农对TypedValue充满好奇,通过查询官网了解该类

TypedValue

  ---android.util.TypedValue

 Container for a dynamically typed data value. Primarily used with  for holding resource values.

 翻译过来就是:这个类是工具类,作为一个动态容器,它存放一些数据值,这些值主要是resource中的值。

我们来理解一下:resource中到底有哪些值?layout、drawable、string、style、anim、dimens、menu、colors、ids这些值一些和屏幕适配有直接的关系。

有一些方法必然是可以读取这些资源文件信息的,比如:

getDimension(DisplayMetrics metrics)

再看具体的方法:

applyDimension(int unit, float value,DisplayMetrics metrics)
第一个参数是单位,第二个参数是对应值,第三个你懂的,封装了显示区域的各种属性值。
对于applyDimension(int unit, float value,DisplayMetrics metrics)中的代码我们来看下
1  public static float applyDimension(int unit, float value, 2                                        DisplayMetrics metrics) 3     { 4         switch (unit) { 5         case COMPLEX_UNIT_PX: 6             return value; 7         case COMPLEX_UNIT_DIP: 8             return value * metrics.density; 9         case COMPLEX_UNIT_SP:10             return value * metrics.scaledDensity;11         case COMPLEX_UNIT_PT:12             return value * metrics.xdpi * (1.0f/72);13         case COMPLEX_UNIT_IN:14             return value * metrics.xdpi;15         case COMPLEX_UNIT_MM:16             return value * metrics.xdpi * (1.0f/25.4f);17         }18         return 0;19     }

其中单位为dip的,将其转化为密度*值,也就是像素值,而单位sp的也将其转化为px值,因此该方法可以能进行

dip-->px

sp-- >px

因此上面

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, value ,DisplayMetrics );

这个方法肯定不能将sp转化为dp,我们判断

dp2sp(50) = 150

sp2dp(50) = 150

convertDipOrPx(50) = 150

convertPxOrDip(50) = 17

将代码运行实际结果与判断结果一致。
接下来我们继续分析

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, value ,DisplayMetrics );

该方法系统本意是用来做什么的?

查看官方说明:

Converts an unpacked complex data value holding a dimension to its final floating point value.

这里就把对应的值转化为实际屏幕上的点值,也就是像素值。

如果是TypedValue.COMPLEX_UNIT_DIP,则乘以显示密度density。

而如果是TypedValue.COMPLEX_UNIT_SP,则乘以像素密度scaledDensity

 

我们继续刨根追底

density和scaledDensity的区别在于

density:The logical density of the display.显示密度density = dpi/160

scaledDensity:A scaling factor for fonts displayed on the display.显示字体的缩放因子 = density

实际上两者的值一样,为了验证这个结论我们随便找两台机器小米2S和华为p7,取出density和scaledDensity是一致的,P7为3.0,小米2S = 2.0

 

因此本文结论转化dp-px,px-dp,sp-px,px-sp

使用下面方法:

1 //转换dip为px  2   public static int convertDipOrPx(Context context, int dip) {  3       float scale = context.getResources().getDisplayMetrics().density;  4       return (int)(dip*scale + 0.5f*(dip>=0?1:-1));  5   }  6     7   //转换px为dip  8   public static int convertPxOrDip(Context context, int px) {  9       float scale = context.getResources().getDisplayMetrics().density; 10      return (int)(px/scale + 0.5f*(px>=0?1:-1)); 11  } 12  13   public static int sp2px(Context context, float spValue) {14         float fontScale = context.getResources().getDisplayMetrics().scaledDensity;15         return (int) (spValue * fontScale + 0.5f);16     }17 18     public static int px2sp(Context context, float pxValue) {19         float fontScale = context.getResources().getDisplayMetrics().scaledDensity;20         return (int) (pxValue / fontScale + 0.5f);21     }

 

如有错误,敬请指正。

 

转载地址:http://lxqyo.baihongyu.com/

你可能感兴趣的文章
19.7 主动模式和被动模式;19.8 添加监控主机;19.9 添加自定义模板;19.10 处理图形中的乱码;19.11...
查看>>
解决FTP服务器命令好使,工具不好使。
查看>>
awk工具(三剑客)
查看>>
Log4j 2 + Slf4j 的配置和使用Apache
查看>>
一次arp防护配置错误导致的故障
查看>>
apt-get install 报错解决办法: Unmet dependencies. Try 'apt-get -f install' with no packages
查看>>
一次反向代理负载均衡的处理过程
查看>>
CentOS.6.6中 PHP-5.5.38安装配置
查看>>
WebDNN:浏览器上运行的最快DNN执行框架(Macbook也行)
查看>>
限制 Top-N 查询结果的记录
查看>>
JdbcTemplate+PageImpl实现多表分页查询
查看>>
Groovy学习随笔之一
查看>>
Centos 5.6 下安装XEN虚拟机以及EMOS
查看>>
C字符串与NSString之间的转换
查看>>
如何快速的提高自己:一切取决于你自己
查看>>
Android JNI入门第一篇——HelloWord
查看>>
关于terracotta在tomcat集群中做session共享的问题
查看>>
调用网页弹窗
查看>>
Windows SQL2008数据库系列一数据的导入导出
查看>>
扩展Label控件(1) - 实现回发(Postback)功能
查看>>