TypedValue.applyDimension 中dp和sp之间转化的真相
转载自http://www.cnblogs.com/xilinch/p/4444833.html
最近在看了许多关于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 Resources
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 }

如有错误,敬请指正。
TypedValue.applyDimension 中dp和sp之间转化的真相的更多相关文章
- UI设计中px、pt、ppi、dpi、dp、sp之间的关系
UI设计中px.pt.ppi.dpi.dp.sp之间的关系 武汉AAA数字艺术教育 2015-07-24 14:19:50 职业教育 pi px 阅读(3398) 评论(0) 声明:本文由入驻搜狐公众 ...
- Android中常用单位dp,px,sp之间的相互转换
MainActivity如下: package cc.testunitswitch; import android.os.Bundle; import android.util.DisplayMetr ...
- Android单位转换 (px、dp、sp之间的转换工具类)
在Android开发中,涉及到屏幕视频问题的时候,px.dp.sp之间的转换比较重要的一部分,所以杨哥整理了一个工具类给大伙用. package com.zw.express.tool; import ...
- [转]Android中dp,px,sp概念梳理以及如何做到屏幕适配
http://blog.csdn.net/jiangwei0910410003/article/details/40509571 今天又开始我的App开发,因为之前一直做的是SDK,所以涉及到界面UI ...
- Android px、dp、sp之间相互转换 系统默认12 sp
px 就是像素 sp=dpX字体比例(1.25f) 一.dp(或者dip device independent pixels) 一种基于屏幕密度的抽象单位.在每英寸160点的显示器上,1dp=1px ...
- Android px、dp、sp之间相互转换
dp(dip): device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA.HVGA和QVGA 推荐使用这个,不依赖 ...
- px(像素)、pt(点)、ppi、dpi、dp、sp之间的关系
px:pixel,像素,电子屏幕上组成一幅图画或照片的最基本单元 pt:point,点,印刷行业常用单位,等于1/72英寸 ppi:pixel per inch,每英寸像素数,该值越高,则屏幕越细腻 ...
- Android中dp和px之间进行转换
在xml布局文件中,我们既可以设置px,也可以设置dp(或者dip).一般情况下,我们都会选择使用dp,这样可以保证不同屏幕分辨率的机器上布局一致.但是在代码中,如何处理呢?很多控件的方法中都只提供了 ...
- 在安卓代码中dp 和 sp 换算px
/** * 单位转换工具 * * @author carrey * */ public class DisplayUtil { /** * 将px值转换为dip或dp值,保证尺寸大小不变 * * @p ...
随机推荐
- 每天一个linux命令--su
su命令和su -命令最大的本质区别就是:前者只是切换了root身份,但Shell环境仍然是普通用户的Shell:而后者连用户和Shell环境一起切换成root身份了. [richmail@porta ...
- 【oracle】oracle启动和关闭步骤
前言: 首先要知道,Oracle数据库的完整启动过程是分步骤完成的,包含以下3个步骤: 启动实例-->加载数据库-->打开数据库 因为Oracle数据库启动过程中不同的阶段可以对数据库进行 ...
- iOS之03-类的合理设计
以下代码为了充分学习理解 类与对象 类与对象的定义 类就是将事物的共有属性和方法抽离出来形成的:类是现实世界或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起. 对象是具有类类 ...
- BZOJ3421 : Poi2013 Walk
最多只有一个连通块大小大于$nk$,所以用hash表进行BFS的时候只扩展$nk$步即可. 时间复杂度$O(n^2k)$. #include<cstdio> typedef long lo ...
- hiveserver2
hiveserver2 默认绑定了ip:localhost 和 port:10000 !connect jdbc:hive2://localhost:10000 org.apache.hive.jd ...
- jsp页面中创建方法
在JSP页面中是用 <%! void function(){ } %> 这种方式可以定义函数. 如果只使用 <% //todo %> 代码块中的代码在编译时将会都被加到 sev ...
- Spoj 10628. Count on a tree 题解
题目大意: 给定一棵n个点的树,每个点有一个权值,m个询问,每次询问树上点x到点y的路径上的第k小数. 思路: dfs后给每个节点一个dfs序,以每个点在他父亲的基础上建立主席树,询问时用(点x+点y ...
- BZOJ1798[Ahoi2009]Seq 维护序列seq 题解
题目大意: 有长为N的数列,有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值. ...
- spring源码学习之路---深度分析IOC容器初始化过程(四)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 最近由于工作和生活,学习耽搁 ...
- nmap的script参数列表
在新的nmap版本中,添加了script功能的使用.在nmap的安装目录的share/nmap/scripts中,已经有将61个写好的脚本提供. 具体的用法可以参考:http://nmap.org/b ...