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方法得到的返回值最为精确。getDimensionPixelOffset方法得到的返回值为舍去小数后的int型。getDimensionPixelSize 方法得到的返回值为四舍五入后的int型。