方法getDimension, getDimensionPixelOffset, 和 getDimensionPixelSize都是用于从资源文件 dimens.xml 或 dimen.xml 中检索指定资源ID的尺寸值, 并转换成像素(px),但它们在处理所检索的尺寸值时各有不同:
getDimension(@DimenRes int id)
- 目的: 检索资源ID指定的尺寸值。这个方法返回的是原始尺寸值乘以当前
DisplayMetrics关联的像素密度(density)后的结果。 - 返回类型:
float。返回值是一个浮点数,提供更精确的尺寸值,适用于需要高精度的场景。
getDimensionPixelOffset(@DimenRes int id)
- 目的: 与
getDimension相似,用于检索特定资源ID的尺寸值。不同之处在于,它将返回的值转换为整数像素,并且转换过程中直接截断(舍去)小数部分。 - 返回类型:
int。返回值是一个整数,表示以像素为单位的尺寸。
getDimensionPixelSize(@DimenRes int id)
-
目的: 与
getDimension相似,用于检索特定资源ID的尺寸值。它将浮点数四舍五入到最近的整数,并确保非零的基值小于或等于一个像素大小。 -
返回类型:
int。同样返回一个整数,表示以像素为单位的尺寸,但是它保证了至少有一个像素的大小。假设
getResource().getDisplayMetrics().density = 1, 经过方法getDimensionPixelSize(@DimenRes int id)的转换如下:
2.3dp -> 2px
2.5dp -> 3px
2.7dp -> 3px
0.3dp -> 1px
总结:这三个方法的主要区别在于它们如何处理原始的浮点维度值。getDimension提供最精确的值(浮点数),getDimensionPixelOffset通过截断小数部分提供一个粗略的整数值,而getDimensionPixelSize通过四舍五入,并保证非零值至少为1像素,提供一个更为实用的整数值。选择哪个方法取决于特定场景下对尺寸精度的需求。
源码如下:
/**
* Retrieve a dimensional for a particular resource ID. Unit
* conversions are based on the current {@link DisplayMetrics} associated
* with the resources.
*
* @param id The desired resource identifier, as generated by the aapt
* tool. This integer encodes the package, type, and resource
* entry. The value 0 is an invalid identifier.
*
* @return Resource dimension value multiplied by the appropriate
* metric.
*
* @throws NotFoundException Throws NotFoundException if the given ID does not exist.
*
* @see #getDimensionPixelOffset
* @see #getDimensionPixelSize
*/
public float getDimension(@DimenRes int id) throws NotFoundException {
final TypedValue value = obtainTempTypedValue();
try {
final ResourcesImpl impl = mResourcesImpl;
impl.getValue(id, value, true);
if (value.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimension(value.data, impl.getDisplayMetrics());
}
throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+ " type #0x" + Integer.toHexString(value.type) + " is not valid");
} finally {
releaseTempTypedValue(value);
}
}
/**
* Retrieve a dimensional for a particular resource ID for use
* as an offset in raw pixels. This is the same as
* {@link #getDimension}, except the returned value is converted to
* integer pixels for you. An offset conversion involves simply
* truncating the base value to an integer.
*
* @param id The desired resource identifier, as generated by the aapt
* tool. This integer encodes the package, type, and resource
* entry. The value 0 is an invalid identifier.
*
* @return Resource dimension value multiplied by the appropriate
* metric and truncated to integer pixels.
*
* @throws NotFoundException Throws NotFoundException if the given ID does not exist.
*
* @see #getDimension
* @see #getDimensionPixelSize
*/
public int getDimensionPixelOffset(@DimenRes int id) throws NotFoundException {
final TypedValue value = obtainTempTypedValue();
try {
final ResourcesImpl impl = mResourcesImpl;
impl.getValue(id, value, true);
if (value.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelOffset(value.data,
impl.getDisplayMetrics());
}
throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+ " type #0x" + Integer.toHexString(value.type) + " is not valid");
} finally {
releaseTempTypedValue(value);
}
}
/**
* Retrieve a dimensional for a particular resource ID for use
* as a size in raw pixels. This is the same as
* {@link #getDimension}, except the returned value is converted to
* integer pixels for use as a size. A size conversion involves
* rounding the base value, and ensuring that a non-zero base value
* is at least one pixel in size.
*
* @param id The desired resource identifier, as generated by the aapt
* tool. This integer encodes the package, type, and resource
* entry. The value 0 is an invalid identifier.
*
* @return Resource dimension value multiplied by the appropriate
* metric and truncated to integer pixels.
*
* @throws NotFoundException Throws NotFoundException if the given ID does not exist.
*
* @see #getDimension
* @see #getDimensionPixelOffset
*/
public int getDimensionPixelSize(@DimenRes int id) throws NotFoundException {
final TypedValue value = obtainTempTypedValue();
try {
final ResourcesImpl impl = mResourcesImpl;
impl.getValue(id, value, true);
if (value.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelSize(value.data, impl.getDisplayMetrics());
}
throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+ " type #0x" + Integer.toHexString(value.type) + " is not valid");
} finally {
releaseTempTypedValue(value);
}
}