【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.虽然是个小问题 ...
随机推荐
- selenium2断言类Assert的使用
测试中断言的重要性 一.断言的作用: 1.断言也就是检查点,重在判断我们通过页面得出来的值与期望值是否相等,如果相等,则代表断言成功,程序会继续往下执行,如果不相等,则代表断言失败,程序就会在断言失败 ...
- JAVA里的单引号和双引号及String和char的区别
JAVA里的单引号和双引号及String和char的区别 单引号引的数据 是char类型的双引号引的数据 是String类型的单引号只能引一个字符而双引号可以引0个及其以上 ************* ...
- 两种图片延迟加载的方法总结jquery.scrollLoading.js与jquery.lazyload.js
估计网上能查到的最多的两种图片延迟加载方法就是jquery.scrollLoading.js与jquery.lazyload.js了,其中jquery.lazyload.js的调用方法因为有网友爆出的 ...
- Leetcode 459.重复的子字符串
重复的子字符串 给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成.给定的字符串只含有小写英文字母,并且长度不超过10000. 示例 1: 输入: "abab" 输出: ...
- pip installl安装包特别慢? 指定源进行安装
指定源地址安装: pip install -i http://pypi.douban.com/simple/ packagename pip install -i http://pypi.tuna.t ...
- Hibernate的简单封装Session(方便调用)
因为每次用增删改查时都需要用到hibernate的配置来生成session工厂进而生成session,比较麻烦,所以我们直接封装一个可以调用的类,需要的时候只需要调用即可. 新建一个Hibernate ...
- google chrome & preferences & languages
google chrome & preferences & languages language settings https://www.google.com/preferences ...
- win install pip
在windows下,我们使用python时,常常因为找不到需要的pthon模块,导致一些脚本不能正常执行,这时候可以安装pip工具,使用它来管理安装python所需要的模块: pip install ...
- maven项目中配置mvn源
在pom.xml中配置 <repositories> <!--for others--> <repository> <id>alimaven</i ...
- poj 3293 Rectilinear polygon
Rectilinear polygon Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2125 Accepted: 24 ...