/**
* Retrieve a dimensional unit attribute at index. Unit
* conversions are based on the current {@link DisplayMetrics}
* associated with the resources this {@link TypedArray} object
* came from.
*
* 通过指定的 参数inde 获得一个尺寸的单位属性。该单位转换是基于你当前机器屏幕的DisplayMetrics
* 以及和当前TypedArray 的对象持有的资源而得到的,
*
* This method will throw an exception if the attribute is defined but is
* not a dimension.
* 当属性不是尺寸的时候,即使确实被定义了,也会抛出一个异常的。
* @param index Index of attribute to retrieve.
* @param defValue Value to return if the attribute is not defined or
* not a resource.
*
* @return Attribute dimension value multiplied by the appropriate
* metric, or defValue if not defined.
* 结果将被乘上一个合适的 metric
* @throws RuntimeException if the TypedArray has already been recycled.
* 如果当前TypedArray 被recycle 会抛异常
* @throws UnsupportedOperationException if the attribute is defined but is
* not an integer.
* 如果定义的属性不是整形,会抛异常
*
* @see #getDimensionPixelOffset
* @see #getDimensionPixelSize
*/
public float getDimension(int index, float defValue) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
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*AssetManager.STYLE_NUM_ENTRIES, value);
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + index + ": " + value);
}
throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
+ Integer.toHexString(type));
}
}
/**
* Retrieve a dimensional unit attribute at index 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.
*
* 通过 参数 index 获取一个在原始像素上使用一个偏移(offset)尺寸单位。除了返回值类型是整形(单位是像素),
* 其他的和getDimension一样,偏移也涉及到简单的转换(怎么转换呢,其实就是强转为int 类型了)
*
* This method will throw an exception if the attribute is defined but is
* not a dimension.
*
* @param index Index of attribute to retrieve.
* @param defValue Value to return if the attribute is not defined or
* not a resource.
*
* @return Attribute dimension value multiplied by the appropriate
* metric and truncated to integer pixels, or defValue if not defined.
* @throws RuntimeException if the TypedArray has already been recycled.
* @throws UnsupportedOperationException if the attribute is defined but is
* not an integer.
*
* @see #getDimension
* @see #getDimensionPixelSize
*/
public int getDimensionPixelOffset(int index, int defValue) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
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*AssetManager.STYLE_NUM_ENTRIES, value);
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + index + ": " + value);
}
throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
+ Integer.toHexString(type));
}
/**
* Retrieve a dimensional unit attribute at index 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.
* 通过 参数 index 获取一个在原始像素上的尺寸单位。除了返回值类型是整形(单位是像素),
* 其他的和getDimension一样,也涉及到简单的转换(怎么转换呢,其实是四舍五入成整形了)
*
* This method will throw an exception if the attribute is defined but is
* not a dimension.
*
* @param index Index of attribute to retrieve.
* @param defValue Value to return if the attribute is not defined or
* not a resource.
*
* @return Attribute dimension value multiplied by the appropriate
* metric and truncated to integer pixels, or defValue if not defined.
* @throws RuntimeException if the TypedArray has already been recycled.
* @throws UnsupportedOperationException if the attribute is defined but is
* not a dimension.
*
* @see #getDimension
* @see #getDimensionPixelOffset
*/
public int getDimensionPixelSize(int index, int defValue) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
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*AssetManager.STYLE_NUM_ENTRIES, value);
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + index + ": " + value);
}
throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
+ Integer.toHexString(type));
}
return TypedValue.complexToDimension(
data[index + AssetManager.STYLE_DATA], mMetrics);
return TypedValue.complexToDimensionPixelOffset(
data[index + AssetManager.STYLE_DATA], mMetrics);
return TypedValue.complexToDimensionPixelSize(
data[index + AssetManager.STYLE_DATA], mMetrics);
public static float complexToDimension(int data, DisplayMetrics metrics) {
return applyDimension(
(data >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK,
complexToFloat(data),
metrics);
}
public static int complexToDimensionPixelOffset(int data,
DisplayMetrics metrics) {
/**
* 这里只是强转,相当于调用了 return (int)complexToDimension(data,metrics)
*/
return (int) applyDimension(
(data >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK,
complexToFloat(data),
metrics);
}
public static int complexToDimensionPixelSize(int data,
DisplayMetrics metrics) {
final float value = complexToFloat(data);
/**
* 这一步相当于 f = complexToDimension(data,metrics),下面就是将f 变化了
*/
final float f = applyDimension(
(data >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK,
value,
metrics);
/**
* 这一步就是四舍五入
*/
final int res = (int) (f + 0.5f);
if (res != 0) return res;
if (value == 0) return 0;
if (value > 0) return 1;
return -1;
}
private void init(Context context, AttributeSet attrs) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.WaterFallLayout);
mColums = array.getInteger(R.styleable.WaterFallLayout_colum, DEFAULT_COLUMS);
float dimension = array.getDimension(R.styleable.WaterFallLayout_margin,DEFAULT_MARGIN);
int pixelSize = array.getDimensionPixelSize(R.styleable.WaterFallLayout_margin,DEFAULT_MARGIN);
int pixelOffset = array.getDimensionPixelOffset(R.styleable.WaterFallLayout_margin,DEFAULT_MARGIN);
array.recycle();
Log.e(TAG, "getDimension==>" + dimension);
Log.e(TAG, "getDimensionPixelSize==>" + pixelSize);
Log.e(TAG, "getDimensionPixelOffset==>" + pixelOffset);
}
09-07 03:34:17.223 25181-25181/com.example.test1 E/WaterFallLayout:getDimension==>43.5
09-07 03:34:17.223 25181-25181/com.example.test1 E/WaterFallLayout:getDimensionPixelSize==>44
09-07 03:34:50.231 25181-25181/com.example.test1 E/WaterFallLayout:getDimensionPixelOffset==>43