getDimension 的源码如下
public float getDimension(@StyleableRes int index, float defValue) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
final int attrIndex = index;
index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimension(
data[index + AssetManager.STYLE_DATA], mMetrics);
} else if (type == TypedValue.TYPE_ATTRIBUTE) {
final TypedValue value = mValue;
getValueAt(index, value);
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + attrIndex + ": " + value);
}
throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
+ " to dimension: type=0x" + Integer.toHexString(type));
}
getDimensionPixelOffset 的源码如下
public int getDimensionPixelOffset(@StyleableRes int index, int defValue) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
final int attrIndex = index;
index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelOffset(
data[index + AssetManager.STYLE_DATA], mMetrics);
} else if (type == TypedValue.TYPE_ATTRIBUTE) {
final TypedValue value = mValue;
getValueAt(index, value);
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + attrIndex + ": " + value);
}
throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
+ " to dimension: type=0x" + Integer.toHexString(type));
}
getDimensionPixelSize 的源码如下
public int getDimensionPixelSize(@StyleableRes int index, int defValue) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
final int attrIndex = index;
index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelSize(
data[index+AssetManager.STYLE_DATA], mMetrics);
} else if (type == TypedValue.TYPE_ATTRIBUTE) {
final TypedValue value = mValue;
getValueAt(index, value);
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + attrIndex + ": " + value);
}
throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
+ " to dimension: type=0x" + Integer.toHexString(type));
}
可以看到三个方法在没有查到属性返回默认值的时候都是直接返回.不会做任何处理.所以在添加默认值的时候.如果默认值是采用的dp这种单位.记得要乘以density.
三个方法不同处在于type == TypedValue.TYPE_DIMENSION 时.这也就是在获取自定义属性的时候.
我们看看三个方法的不同处
getDimension 的计算方法如下
public static float complexToDimension(int data, DisplayMetrics metrics) {
return applyDimension(
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
complexToFloat(data),
metrics);
}
可以看到,该方法直接返回一个float类型的值.
getDimensionPixelOffset 的计算方法如下
public static int complexToDimensionPixelOffset(int data, DisplayMetrics metrics) {
return (int)applyDimension(
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
complexToFloat(data),
metrics);
}
我们看到,该方法只是简单的将getDimension方法得到的值进行了一下强转. 即 不管getDimension得到的值是20.1, 或者是20.9.强转后都会是20. 即舍去getDimension的小数.
getDimensionPixelSize 的计算方法如下.
public static int complexToDimensionPixelSize(int data, DisplayMetrics metrics) {
final float value = complexToFloat(data);
final float f = applyDimension(
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK, value, metrics);
final int res = (int) ((f >= 0) ? (f + 0.5f) : (f - 0.5f));
if (res != 0) return res;
if (value == 0) return 0;
if (value > 0) return 1;
return -1;
}
我们看到,该方法将getDimension方法得到的值上在加上0.5f. 在进行强转.即 如果getDimension得到的值为20.1,加上0.5后为20.6.强转后为20. 如果getDimension得到的值为20.5,加上0.5后为30.0.强转后为30. 即对getDimension得到的小数点的第一位进行四舍五入.
现在我们验证一下.
在getDimension = 101.599976 时, getDimensionPixelSize 四舍五入后为 102, getDimensionPixelOffset 直接强转为101.
在getDimension = 101.19995 时, getDimensionPixelSize 四舍五入后为 101, getDimensionPixelOffset 直接强转为101.
结果就是getDimension 方法得到的返回值最为精确. getDimensionPixelOffset 方法得到的返回值为舍去小数后的int型. getDimensionPixelSize 方法得到的返回值为四舍五入后的int型.