下面列出了android.util.TypedValue#TYPE_REFERENCE 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Gets a {@link Drawable} from {@link TypedArray} and index of attribute.
*
* @param context
* the required context.
*
* @param typedArray
* the array of values.
* @param index
* the index of the attribute.
*
* @return a {@link Drawable} or null if a raw TypedValue could not be retrieved.
* @throws IllegalArgumentException if the attribute at index cannot be resolved.
*/
public static Drawable getDrawable(Context context, final TypedArray typedArray, final int index) {
final TypedValue value = typedArray.peekValue(index);
if (value == null) {
return null;
}
if (value.type == TypedValue.TYPE_REFERENCE || value.type == TypedValue.TYPE_STRING) {
// if it is reference to some drawable.
return typedArray.getDrawable(index);
} else if (value.type == TypedValue.TYPE_INT_COLOR_ARGB8 || value.type == TypedValue.TYPE_INT_COLOR_ARGB4 || value.type ==
TypedValue.TYPE_INT_COLOR_RGB8 || value.type == TypedValue.TYPE_INT_COLOR_RGB4) {
// if it is reference to some color.
return new ColorDrawable(typedArray.getColor(index, 0xFF000000)); // black color
} else {
throw new IllegalArgumentException(
context.getString(R.string.msdkui_exception_attribute_invalid, index));
}
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
if (!customTheme){
// theme specified by the imageDialogTheme attribute or default
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(R.attr.imageDialogTheme, outValue, true);
if (outValue.type == TypedValue.TYPE_REFERENCE) {
theme(outValue.resourceId);
} else {
theme(R.style.ImageDialogTheme);
}
}
return super.onCreateDialog(savedInstanceState);
}
public int getIdAttributeResourceValue(int defaultValue) {
if (m_idAttribute == -1) {
return defaultValue;
}
int offset = getAttributeOffset(m_idAttribute);
int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE];
if (valueType != TypedValue.TYPE_REFERENCE) {
return defaultValue;
}
return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA];
}
private static String getAttributeValue(XmlResourceParser parser, int index) {
int type = parser.getAttributeValueType(index);
int data = parser.getAttributeValueData(index);
if (type == TypedValue.TYPE_STRING) {
return parser.getAttributeValue(index);
}
if (type == TypedValue.TYPE_ATTRIBUTE) {
return String.format("?%s%08X", getPackage(data), data);
}
if (type == TypedValue.TYPE_REFERENCE) {
return String.format("@%s%08X", getPackage(data), data);
}
if (type == TypedValue.TYPE_FLOAT) {
return String.valueOf(Float.intBitsToFloat(data));
}
if (type == TypedValue.TYPE_INT_HEX) {
return String.format("0x%08X", data);
}
if (type == TypedValue.TYPE_INT_BOOLEAN) {
return data != 0 ? "true" : "false";
}
if (type == TypedValue.TYPE_DIMENSION) {
return Float.toString(complexToFloat(data))
+ DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type == TypedValue.TYPE_FRACTION) {
return Float.toString(complexToFloat(data))
+ FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type >= TypedValue.TYPE_FIRST_COLOR_INT
&& type <= TypedValue.TYPE_LAST_COLOR_INT) {
return String.format("#%08X", data);
}
if (type >= TypedValue.TYPE_FIRST_INT
&& type <= TypedValue.TYPE_LAST_INT) {
return String.valueOf(data);
}
return String.format("<0x%X, type 0x%02X>", data, type);
}
private static String getAttributeValue(AXmlResourceParser parser, int index) {
int type = parser.getAttributeValueType(index);
int data = parser.getAttributeValueData(index);
if (type == TypedValue.TYPE_STRING) {
return parser.getAttributeValue(index);
}
if (type == TypedValue.TYPE_ATTRIBUTE) {
return String.format("?%s%08X", getPackage(data), data);
}
if (type == TypedValue.TYPE_REFERENCE) {
return String.format("@%s%08X", getPackage(data), data);
}
if (type == TypedValue.TYPE_FLOAT) {
return String.valueOf(Float.intBitsToFloat(data));
}
if (type == TypedValue.TYPE_INT_HEX) {
return String.format("0x%08X", data);
}
if (type == TypedValue.TYPE_INT_BOOLEAN) {
return data == 0 ? "false" : "true";
}
if (type == TypedValue.TYPE_DIMENSION) {
return Float.toString(complexToFloat(data)) +
DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type == TypedValue.TYPE_FRACTION) {
return Float.toString(complexToFloat(data)) +
FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type >= TypedValue.TYPE_FIRST_COLOR_INT && type <= TypedValue.TYPE_LAST_COLOR_INT) {
return String.format("#%08X", data);
}
if (type >= TypedValue.TYPE_FIRST_INT && type <= TypedValue.TYPE_LAST_INT) {
return String.valueOf(data);
}
return String.format("<0x%X, type 0x%02X>", data, type);
}
private static String getAttributeValue(XmlResourceParser parser, int index) {
int type = parser.getAttributeValueType(index);
int data = parser.getAttributeValueData(index);
if (type == TypedValue.TYPE_STRING) {
return parser.getAttributeValue(index);
}
if (type == TypedValue.TYPE_ATTRIBUTE) {
return String.format("?%s%08X", getPackage(data), data);
}
if (type == TypedValue.TYPE_REFERENCE) {
return String.format("@%s%08X", getPackage(data), data);
}
if (type == TypedValue.TYPE_FLOAT) {
return String.valueOf(Float.intBitsToFloat(data));
}
if (type == TypedValue.TYPE_INT_HEX) {
return String.format("0x%08X", data);
}
if (type == TypedValue.TYPE_INT_BOOLEAN) {
return data != 0 ? "true" : "false";
}
if (type == TypedValue.TYPE_DIMENSION) {
return Float.toString(complexToFloat(data)) + DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type == TypedValue.TYPE_FRACTION) {
return Float.toString(complexToFloat(data)) + FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type >= TypedValue.TYPE_FIRST_COLOR_INT && type <= TypedValue.TYPE_LAST_COLOR_INT) {
return String.format("#%08X", data);
}
if (type >= TypedValue.TYPE_FIRST_INT && type <= TypedValue.TYPE_LAST_INT) {
return String.valueOf(data);
}
if (type == 0x07) {
return String.format("@%s%08X", getPackage(data), data);
}
return String.format("<0x%X, type 0x%02X>", data, type);
}
@Test
public void testGetDrawableWhenTypeIsReference() {
TypedArray typedArray = mock(TypedArray.class);
TypedValue typedValue = spy(new TypedValue());
typedValue.type = TypedValue.TYPE_REFERENCE;
when(typedArray.peekValue(anyInt())).thenReturn(typedValue);
ThemeUtil.getDrawable(getApplicationContext(), typedArray, anyInt());
verify(typedArray).getDrawable(anyInt());
}
public int getIdAttributeResourceValue(int defaultValue) {
if (m_idAttribute == -1) {
return defaultValue;
}
int offset = getAttributeOffset(m_idAttribute);
int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE];
if (valueType != TypedValue.TYPE_REFERENCE) {
return defaultValue;
}
return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA];
}
public int getAttributeResourceValue(int index, int defaultValue) {
int offset = getAttributeOffset(index);
int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE];
if (valueType == TypedValue.TYPE_REFERENCE) {
return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA];
}
return defaultValue;
}
public int getIdAttributeResourceValue(int defaultValue) {
if (m_idAttribute==-1) {
return defaultValue;
}
int offset=getAttributeOffset(m_idAttribute);
int valueType=m_attributes[offset+ATTRIBUTE_IX_VALUE_TYPE];
if (valueType!=TypedValue.TYPE_REFERENCE) {
return defaultValue;
}
return m_attributes[offset+ATTRIBUTE_IX_VALUE_DATA];
}
private static String getAttributeValue(AXmlResourceParser parser, int index) {
int type = parser.getAttributeValueType(index);
int data = parser.getAttributeValueData(index);
if (type == TypedValue.TYPE_STRING) {
return parser.getAttributeValue(index);
}
if (type == TypedValue.TYPE_ATTRIBUTE) {
return String.format("?%s%08X", getPackage(data), data);
}
if (type == TypedValue.TYPE_REFERENCE) {
return String.format("@%s%08X", getPackage(data), data);
}
if (type == TypedValue.TYPE_FLOAT) {
return String.valueOf(Float.intBitsToFloat(data));
}
if (type == TypedValue.TYPE_INT_HEX) {
return String.format("0x%08X", data);
}
if (type == TypedValue.TYPE_INT_BOOLEAN) {
return data != 0 ? "true" : "false";
}
if (type == TypedValue.TYPE_DIMENSION) {
return Float.toString(complexToFloat(data)) +
DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type == TypedValue.TYPE_FRACTION) {
return Float.toString(complexToFloat(data)) +
FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type >= TypedValue.TYPE_FIRST_COLOR_INT && type <= TypedValue.TYPE_LAST_COLOR_INT) {
return String.format("#%08X", data);
}
if (type >= TypedValue.TYPE_FIRST_INT && type <= TypedValue.TYPE_LAST_INT) {
return String.valueOf(data);
}
return String.format("<0x%X, type 0x%02X>", data, type);
}
public ResScalarValue factory(int type, int value, String rawValue) throws IOException {
switch (type) {
case TypedValue.TYPE_NULL:
return new ResReferenceValue(mPackage, 0, null);
case TypedValue.TYPE_REFERENCE:
return newReference(value, rawValue);
case TypedValue.TYPE_ATTRIBUTE:
return newReference(value, rawValue, true);
case TypedValue.TYPE_STRING:
return new ResStringValue(rawValue, value);
case TypedValue.TYPE_FLOAT:
return new ResFloatValue(Float.intBitsToFloat(value), value, rawValue);
case TypedValue.TYPE_DIMENSION:
return new ResDimenValue(value, rawValue);
case TypedValue.TYPE_FRACTION:
return new ResFractionValue(value, rawValue);
case TypedValue.TYPE_INT_BOOLEAN:
return new ResBoolValue(value != 0, value, rawValue);
case 0x07:
return newReference(value, rawValue);
}
if (type >= TypedValue.TYPE_FIRST_COLOR_INT && type <= TypedValue.TYPE_LAST_COLOR_INT) {
return new ResColorValue(value, rawValue);
}
if (type >= TypedValue.TYPE_FIRST_INT && type <= TypedValue.TYPE_LAST_INT) {
return new ResIntValue(value, rawValue, type);
}
throw new IOException("Invalid value type: " + type);
}
public int getAttributeResourceValue(int index, int defaultValue) {
int offset = getAttributeOffset(index);
int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE];
if (valueType == TypedValue.TYPE_REFERENCE) {
return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA];
}
return defaultValue;
}
public static String getAttributeValue(AXmlResourceParser parser,int index) {
int type=parser.getAttributeValueType(index);
int data=parser.getAttributeValueData(index);
if (type==TypedValue.TYPE_STRING) {
return parser.getAttributeValue(index);
}
if (type==TypedValue.TYPE_ATTRIBUTE) {
return String.format("?%s%08X",getPackage(data),data);
}
if (type==TypedValue.TYPE_REFERENCE) {
return String.format("@%s%08X",getPackage(data),data);
}
if (type==TypedValue.TYPE_FLOAT) {
return String.valueOf(Float.intBitsToFloat(data));
}
if (type==TypedValue.TYPE_INT_HEX) {
return String.format("0x%08X",data);
}
if (type==TypedValue.TYPE_INT_BOOLEAN) {
return data!=0?"true":"false";
}
if (type==TypedValue.TYPE_DIMENSION) {
return Float.toString(complexToFloat(data))+
DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type==TypedValue.TYPE_FRACTION) {
return Float.toString(complexToFloat(data))+
FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type>=TypedValue.TYPE_FIRST_COLOR_INT && type<=TypedValue.TYPE_LAST_COLOR_INT) {
return String.format("#%08X",data);
}
if (type>=TypedValue.TYPE_FIRST_INT && type<=TypedValue.TYPE_LAST_INT) {
return String.valueOf(data);
}
return String.format("<0x%X, type 0x%02X>",data,type);
}
public int getIdAttributeResourceValue(int defaultValue) {
if (m_idAttribute==-1) {
return defaultValue;
}
int offset=getAttributeOffset(m_idAttribute);
int valueType=m_attributes[offset+ATTRIBUTE_IX_VALUE_TYPE];
if (valueType!=TypedValue.TYPE_REFERENCE) {
return defaultValue;
}
return m_attributes[offset+ATTRIBUTE_IX_VALUE_DATA];
}
public int getAttributeResourceValue(int index,int defaultValue) {
int offset=getAttributeOffset(index);
int valueType=m_attributes[offset+ATTRIBUTE_IX_VALUE_TYPE];
if (valueType==TypedValue.TYPE_REFERENCE) {
return m_attributes[offset+ATTRIBUTE_IX_VALUE_DATA];
}
return defaultValue;
}
public int getAttributeResourceValue(int index, int defaultValue) {
int offset = getAttributeOffset(index);
int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE];
if (valueType == TypedValue.TYPE_REFERENCE) {
return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA];
}
return defaultValue;
}
public int getIdAttributeResourceValue(int defaultValue) {
if (m_idAttribute == -1) {
return defaultValue;
}
int offset = getAttributeOffset(m_idAttribute);
int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE];
if (valueType != TypedValue.TYPE_REFERENCE) {
return defaultValue;
}
return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA];
}
private static String getAttributeValue(AXmlResourceParser parser, int index) {
int type = parser.getAttributeValueType(index);
int data = parser.getAttributeValueData(index);
if (type == TypedValue.TYPE_STRING) {
return parser.getAttributeValue(index);
}
if (type == TypedValue.TYPE_ATTRIBUTE) {
return String.format("?%s%08X", getPackage(data), data);
}
if (type == TypedValue.TYPE_REFERENCE) {
return String.format("@%s%08X", getPackage(data), data);
}
if (type == TypedValue.TYPE_FLOAT) {
return String.valueOf(Float.intBitsToFloat(data));
}
if (type == TypedValue.TYPE_INT_HEX) {
return String.format("0x%08X", data);
}
if (type == TypedValue.TYPE_INT_BOOLEAN) {
return data != 0 ? "true" : "false";
}
if (type == TypedValue.TYPE_DIMENSION) {
return Float.toString(complexToFloat(data))
+ DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type == TypedValue.TYPE_FRACTION) {
return Float.toString(complexToFloat(data))
+ FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
}
if (type >= TypedValue.TYPE_FIRST_COLOR_INT
&& type <= TypedValue.TYPE_LAST_COLOR_INT) {
return String.format("#%08X", data);
}
if (type >= TypedValue.TYPE_FIRST_INT
&& type <= TypedValue.TYPE_LAST_INT) {
return String.valueOf(data);
}
return String.format("<0x%X, type 0x%02X>", data, type);
}
private void getAttributes(Context context, @Nullable AttributeSet attrs)
{
// According to docs for obtainStyledAttributes, attrs can be null and I assume that each value will be set
// to the default
final TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SegmentedButtonGroup, 0, 0);
// Load background if available, this can be a drawable or a color
// Note: Not well documented but getDrawable will return a ColorDrawable if a color is specified
if (ta.hasValue(R.styleable.SegmentedButtonGroup_android_background))
backgroundDrawable = ta.getDrawable(R.styleable.SegmentedButtonGroup_android_background);
// Load background on selection if available, can be drawable or color
if (ta.hasValue(R.styleable.SegmentedButtonGroup_selectedBackground))
selectedBackgroundDrawable = ta.getDrawable(R.styleable.SegmentedButtonGroup_selectedBackground);
// Note: Must read radius before setBorder call in order to round the border corners!
radius = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_radius, 0);
selectedButtonRadius = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_selectedButtonRadius, 0);
// Setup border for button group
// Width is the thickness of the border, color is the color of the border
// Dash width and gap, if the dash width is not zero will make the border dashed with a ratio between dash
// width and gap
borderWidth = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_borderWidth, 0);
borderColor = ta.getColor(R.styleable.SegmentedButtonGroup_borderColor, Color.BLACK);
borderDashWidth = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_borderDashWidth, 0);
borderDashGap = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_borderDashGap, 0);
// Set the border to the read values, this will set the border values to itself but will create a
// GradientDrawable containing the border
setBorder(borderWidth, borderColor, borderDashWidth, borderDashGap);
// Get border information for the selected button
// Same defaults as the border above, however this border information will be passed to each button so that
// the correct border can be rendered around the selected button
selectedBorderWidth = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_selectedBorderWidth, 0);
selectedBorderColor = ta.getColor(R.styleable.SegmentedButtonGroup_selectedBorderColor, Color.BLACK);
selectedBorderDashWidth = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_selectedBorderDashWidth, 0);
selectedBorderDashGap = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_selectedBorderDashGap, 0);
position = ta.getInt(R.styleable.SegmentedButtonGroup_position, 0);
draggable = ta.getBoolean(R.styleable.SegmentedButtonGroup_draggable, false);
// Update clickable property
// Not updating this property sets the clickable value to false by default but this sets the default to true
// while keeping the clickable value if specified in the layouot XML
setClickable(ta.getBoolean(R.styleable.SegmentedButtonGroup_android_clickable, true));
ripple = ta.getBoolean(R.styleable.SegmentedButtonGroup_ripple, true);
hasRippleColor = ta.hasValue(R.styleable.SegmentedButtonGroup_rippleColor);
rippleColor = ta.getColor(R.styleable.SegmentedButtonGroup_rippleColor, Color.GRAY);
final int dividerWidth = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_dividerWidth, 1);
final int dividerRadius = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_dividerRadius, 0);
final int dividerPadding = ta.getDimensionPixelSize(R.styleable.SegmentedButtonGroup_dividerPadding, 0);
// Load divider value if available, the divider can be either a drawable resource or a color
// Load the TypedValue first and check the type to determine if color or drawable
final TypedValue value = new TypedValue();
if (ta.getValue(R.styleable.SegmentedButtonGroup_divider, value))
{
if (value.type == TypedValue.TYPE_REFERENCE || value.type == TypedValue.TYPE_STRING)
{
// Note: Odd case where Android Studio layout preview editor will fail to display a
// SegmentedButtonGroup with a divider drawable because value.resourceId returns 0 and thus
// ContextCompat.getDrawable will return NullPointerException
// Loading drawable TypedArray.getDrawable or doing TypedArray.getResourceId fixes the problem
if (isInEditMode())
{
setDivider(ta.getDrawable(R.styleable.SegmentedButtonGroup_divider), dividerWidth, dividerRadius,
dividerPadding);
}
else
{
setDivider(ContextCompat.getDrawable(context, value.resourceId), dividerWidth, dividerRadius,
dividerPadding);
}
}
else if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT && value.type <= TypedValue.TYPE_LAST_COLOR_INT)
{
// Divider is a color, value.data is the color value
setDivider(value.data, dividerWidth, dividerRadius, dividerPadding);
}
else
{
// Invalid type for the divider, throw an exception
throw new IllegalArgumentException("Invalid type for SegmentedButtonGroup divider in layout XML "
+ "resource. Must be a color or drawable");
}
}
int selectionAnimationInterpolator = ta.getInt(R.styleable.SegmentedButtonGroup_selectionAnimationInterpolator,
ANIM_INTERPOLATOR_FAST_OUT_SLOW_IN);
setSelectionAnimationInterpolator(selectionAnimationInterpolator);
selectionAnimationDuration = ta.getInt(R.styleable.SegmentedButtonGroup_selectionAnimationDuration, 500);
// Recycle the typed array, required once done using it
ta.recycle();
}