【android】getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()区别详解
在自定义控件中使用自定义属性时,经常需要使用java代码获取在xml中定义的尺寸,相关有以下三个函数
- getDimension()
- getDimensionPixelOffset()
- getDimensionPixelSize()
(在类TypedArray和类Resources中都有这三个函数,功能类似,TypedArray中的函数是获取自定义属性的,Resources中的函数是获取android预置属性的)
通常初学者(尤其是洋文不大好的朋友们)看到这三个函数的名称时会有点不知所云。反正在我仔细研究前是这样,getDimensionPixelSize()函数看名称是获取像素,那getDimensionPixelOffset()这玩意儿的offset是啥(通常API里不都是
begin, offset,
len么)? getDimension()这个函数又是干啥的,和getDimensionPixelSize()有什么区别吗,是获取原始的dp值吗(答案是否定的)?
高手请无视本帖,不太明白的初学者可以往下仔细看看哦~
带着这些疑惑,看看API reference里的解释:
- getDimension()是基于当前DisplayMetrics进行转换,获取指定资源id对应的尺寸。文档里并没说这里返回的就是像素,要注意这个函数的返回值是float,像素肯定是int。
- getDimensionPixelSize()与getDimension()功能类似,不同的是将结果转换为int,并且小数部分四舍五入。
- getDimensionPixelOffset()与getDimension()功能类似,不同的是将结果转换为int,并且偏移转换(offset
conversion,函数命名中的offset是这个意思)是直接截断小数位,即取整(其实就是把float强制转化为int,注意不是四舍五入哦)。
由此可见,这三个函数返回的都是绝对尺寸,而不是相对尺寸(dp/sp等)。如果getDimension()返回结果是20.5f,那么getDimensionPixelSize()返回结果就是21,getDimensionPixelOffset()返回结果就是20。
到这里本帖就可以结束了,但如果想知道的多一点,还可以看看android的源代码,来印证上述解释。
深入源码,我们可以发现其实这三个函数实现都很像,以Resources类的getDimension()为例
public float getDimension(int id) throws NotFoundException {
synchronized (mTmpValue) {
TypedValue value = mTmpValue;
getValue(id, value, true);
if (value.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimension(value.data, mMetrics);
}
throw new NotFoundException(
"Resource ID #0x" + Integer.toHexString(id) + " type #0x"
+ Integer.toHexString(value.type) + " is not valid");
}
}
类TypedValue是动态类型数据的容器,主要用于盛放resource的值。上述代码第4行就是根据resId获取TypedValue的值,getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()函数体唯一的不同就是第4行:
- getDimension()调用的是TypedValue的complexToDimension方法
- getDimensionPixelSize调用的是TypedValue的complexToDimensionPixelSize方法
- getDimensionPixelOffset调用的是TypedValue的complexToDimensionPixelOffset方法
我们再深入类TypedValue,查看complexToDimension()、complexToDimensionPixelSize()和complexToDimensionPixelOffset()函数的区别,会发现这三个函数体内容还是差不多,以complexToDimension()为例:
public static float complexToDimension(int data, DisplayMetrics metrics)
{
return applyDimension(
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
complexToFloat(data),
metrics);
}
complexToDimensionPixelOffset()与complexToDimension()不同的是将结果进行了强制转换,相当于直接截断小数部分;
complexToDimensionPixelSize()是将结果进行四舍五入,四舍五入的代码就是把结果加上0.5f再进行强制转换(因为java的float强制转换为int都是直接舍去小数的;如果大于等于0.5则加上0.5进位,强制转换后舍去小数相当于五入;如果小于0.5则加上0.5后整数部分不变,强制转换舍去小数后相当于四舍,java基础,第一次接触的新手普及下~)
ok了,简单的源码分析完成了。
通过源码分析,进一步验证了getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()的区别,大家以后再用到这三个函数的时候就不用发蒙了。在java代码里很多setWidth(),setHeight()的参数都是像素,即整形,大家根据实际情况,看看如果是四舍五入就调用getDimensionPixelSize(),如果是取整就调用getDimensionPixelOffset()。千万不要setWidth((int)getDimension())
这么写哦!
后记:
android并没有在java代码中直接获取xml中定义的dp/sp的值的API,可能是因为google认为没有必要。但如果实在想得到xml中咱们自己写的dp或sp的值(例如想在日志里输出dp/sp什么的),请参见我的另一个帖子Java代码获取xml中定义的dp/sp值的方法
【android】getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()区别详解的更多相关文章
- android: getDimension, getDimensionPixelOffset 和getDimensionPixelSize 区别
◆结论: getDimension 获取某个dimen的值,如果是dp或sp的单位,将其乘以density,如果是px,则不乘 返回float getDimensionPixelOffset 获取 ...
- getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()区别详解
getDimension()是基于当前DisplayMetrics进行转换,获取指定资源id对应的尺寸.文档里并没说这里返回的就是像素,要注意这个函数的返回值是float,像素肯定是int. getD ...
- Android中getDimension,getDimensionPixelOffset和getDimensionPixelSize 区别
getDimension 获取某个dimen的值,如果是dp或sp的单位,将其乘以density,如果是px,则不乘 返回float getDimensionPixelOffset 获取某个dim ...
- Android中Intent传值与Bundle传值的区别详解
Android中Intent传值与Bundle传值的区别详解 举个例子我现在要从A界面跳转到B界面或者C界面 这样的话 我就需要写2个Intent如果你还要涉及的传值的话 你的Intent就要写两 ...
- SurfaceView 与view区别详解
SurfaceView 与view区别详解 https://blog.csdn.net/u011339364/article/details/83347109 2018年10月24日 17:20:08 ...
- 基于Java的打包jar、war、ear包的作用与区别详解
本篇文章,小编为大家介绍,基于Java的打包jar.war.ear包的作用与区别详解.需要的朋友参考下 以最终客户的角度来看,JAR文件就是一种封装,他们不需要知道jar文件中有多少个.cla ...
- php 去除html标记--strip_tags与htmlspecialchars的区别详解
php 去除html标记--strip_tags与htmlspecialchars的区别详解 作者: 字体:[增加 减小] 类型:转载 时间:2013-06-26 本篇文章是对php中去除html ...
- HTTP POST GET 本质区别详解
HTTP POST GET 本质区别详解 一 原理区别 一般在浏览器中输入网址访问资源都是通过GET方式:在FORM提交中,可以通过Method指定提交方式为GET或者POST,默认为GET提交 Ht ...
- javascript中=、==、===区别详解
javascript中=.==.===区别详解今天在项目开发过中发现在一个小问题.在判断n==""结果当n=0时 n==""结果也返回了true.虽然是个小问题 ...
随机推荐
- /dev/sda is apparently in use by the system; will not make a filesystem here!解决方法
/dev/sda is apparently in use by the system; will not make a filesystem here! 翻译:系统显然在使用,不会在这里做文件系统 ...
- Monkeyrunner脚本的录制与回放
继上一篇monkeyrunner环境搭建:http://www.cnblogs.com/zh-ya-jing/p/4351245.html 之后,我们可以进一步学习monkeyrunner了. 我也是 ...
- HDU 5402 模拟 构造 Travelling Salesman Problem
题意: 有一个n * m的数字矩阵,每个格子放着一个非负整数,从左上角走到右下角,每个格子最多走一次,问所经过的格子的最大权值之和是多少,并且输出一个路径. 分析: 如果n和m有一个是偶数的话,那么只 ...
- 回调深入理解 同步回调 以android中View.OnClickListener为列
现在来分析分析下Android View的点击方法onclick();我们知道onclick()是一个回调方法,当用户点击View就执行这个方法,我们用Button来举例好了 //这个是View的 ...
- [办公软件][2]screenToGif
https://github.com/NickeManarin/ScreenToGif/wiki/help 下载: .Net Framework 4.6.1 https://www.microso ...
- [python subprocess学习篇] 调用系统命令
http://www.jb51.net/article/57208.htm 3).Popen.communicate(input=None):与子进程进行交互.向stdin发送数据,或从stdout和 ...
- POJ 1145 Tree Summing
Tree Summing Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7698 Accepted: 1737 Desc ...
- Java容器jdk1.6 Array
参考:https://www.cnblogs.com/tstd/p/5042087.html 1.定义 顶层接口collection public interface Collection<E& ...
- 【bzoj2521】[Shoi2010]最小生成树 网络流最小割
题目描述 Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可能有多种不同的 ...
- [LOJ#531]「LibreOJ β Round #5」游戏
[LOJ#531]「LibreOJ β Round #5」游戏 试题描述 LCR 三分钟就解决了问题,她自信地输入了结果-- > -- 正在检查程序 -- > -- 检查通过,正在评估智商 ...