private int parseTransition(@NonNull Resources r, @NonNull XmlPullParser parser,
@NonNull AttributeSet attrs, @Nullable Theme theme)
throws XmlPullParserException, IOException {
- int drawableRes = 0;
- int fromId = 0;
- int toId = 0;
- boolean reversible = false;
-
- final int numAttrs = attrs.getAttributeCount();
- for (int i = 0; i < numAttrs; i++) {
- final int stateResId = attrs.getAttributeNameResource(i);
- switch (stateResId) {
- case 0:
- break;
- case R.attr.fromId:
- fromId = attrs.getAttributeResourceValue(i, 0);
- break;
- case R.attr.toId:
- toId = attrs.getAttributeResourceValue(i, 0);
- break;
- case R.attr.drawable:
- drawableRes = attrs.getAttributeResourceValue(i, 0);
- break;
- case R.attr.reversible:
- reversible = attrs.getAttributeBooleanValue(i, false);
- break;
- }
- }
+ // This allows state list drawable item elements to be themed at
+ // inflation time but does NOT make them work for Zygote preload.
+ final TypedArray a = obtainAttributes(r, theme, attrs,
+ R.styleable.AnimatedStateListDrawableTransition);
+ final int fromId = a.getResourceId(
+ R.styleable.AnimatedStateListDrawableTransition_fromId, 0);
+ final int toId = a.getResourceId(
+ R.styleable.AnimatedStateListDrawableTransition_toId, 0);
+ final boolean reversible = a.getBoolean(
+ R.styleable.AnimatedStateListDrawableTransition_reversible, false);
+ Drawable dr = a.getDrawable(
+ R.styleable.AnimatedStateListDrawableTransition_drawable);
+ a.recycle();
- final Drawable dr;
- if (drawableRes != 0) {
- dr = r.getDrawable(drawableRes, theme);
- } else {
+ // Loading child elements modifies the state of the AttributeSet's
+ // underlying parser, so it needs to happen after obtaining
+ // attributes and extracting states.
+ if (dr == null) {
int type;
while ((type = parser.next()) == XmlPullParser.TEXT) {
}
if (type != XmlPullParser.START_TAG) {
throw new XmlPullParserException(
parser.getPositionDescription()
- + ": <item> tag requires a 'drawable' attribute or "
+ + ": <transition> tag requires a 'drawable' attribute or "
+ "child tag defining a drawable");
}
dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
private int parseItem(@NonNull Resources r, @NonNull XmlPullParser parser,
@NonNull AttributeSet attrs, @Nullable Theme theme)
throws XmlPullParserException, IOException {
- int drawableRes = 0;
- int keyframeId = 0;
-
- int j = 0;
- final int numAttrs = attrs.getAttributeCount();
- int[] states = new int[numAttrs];
- for (int i = 0; i < numAttrs; i++) {
- final int stateResId = attrs.getAttributeNameResource(i);
- switch (stateResId) {
- case 0:
- break;
- case R.attr.id:
- keyframeId = attrs.getAttributeResourceValue(i, 0);
- break;
- case R.attr.drawable:
- drawableRes = attrs.getAttributeResourceValue(i, 0);
- break;
- default:
- final boolean hasState = attrs.getAttributeBooleanValue(i, false);
- states[j++] = hasState ? stateResId : -stateResId;
- }
- }
- states = StateSet.trimStateSet(states, j);
+ // This allows state list drawable item elements to be themed at
+ // inflation time but does NOT make them work for Zygote preload.
+ final TypedArray a = obtainAttributes(r, theme, attrs,
+ R.styleable.AnimatedStateListDrawableItem);
+ final int keyframeId = a.getResourceId(R.styleable.AnimatedStateListDrawableItem_id, 0);
+ Drawable dr = a.getDrawable(R.styleable.AnimatedStateListDrawableItem_drawable);
+ a.recycle();
- final Drawable dr;
- if (drawableRes != 0) {
- dr = r.getDrawable(drawableRes, theme);
- } else {
+ final int[] states = extractStateSet(attrs);
+
+ // Loading child elements modifies the state of the AttributeSet's
+ // underlying parser, so it needs to happen after obtaining
+ // attributes and extracting states.
+ if (dr == null) {
int type;
while ((type = parser.next()) == XmlPullParser.TEXT) {
}
continue;
}
- int drawableRes = 0;
-
- int i;
- int j = 0;
- final int numAttrs = attrs.getAttributeCount();
- int[] states = new int[numAttrs];
- for (i = 0; i < numAttrs; i++) {
- final int stateResId = attrs.getAttributeNameResource(i);
- if (stateResId == 0) break;
- if (stateResId == R.attr.drawable) {
- drawableRes = attrs.getAttributeResourceValue(i, 0);
- } else {
- states[j++] = attrs.getAttributeBooleanValue(i, false)
- ? stateResId
- : -stateResId;
- }
- }
- states = StateSet.trimStateSet(states, j);
-
- final Drawable dr;
- if (drawableRes != 0) {
- dr = r.getDrawable(drawableRes, theme);
- } else {
+ // This allows state list drawable item elements to be themed at
+ // inflation time but does NOT make them work for Zygote preload.
+ final TypedArray a = obtainAttributes(r, theme, attrs,
+ R.styleable.StateListDrawableItem);
+ Drawable dr = a.getDrawable(R.styleable.StateListDrawableItem_drawable);
+ a.recycle();
+
+ final int[] states = extractStateSet(attrs);
+
+ // Loading child elements modifies the state of the AttributeSet's
+ // underlying parser, so it needs to happen after obtaining
+ // attributes and extracting states.
+ if (dr == null) {
while ((type = parser.next()) == XmlPullParser.TEXT) {
}
if (type != XmlPullParser.START_TAG) {
}
}
+ /**
+ * Extracts state_ attributes from an attribute set.
+ *
+ * @param attrs The attribute set.
+ * @return An array of state_ attributes.
+ */
+ int[] extractStateSet(AttributeSet attrs) {
+ int j = 0;
+ final int numAttrs = attrs.getAttributeCount();
+ int[] states = new int[numAttrs];
+ for (int i = 0; i < numAttrs; i++) {
+ final int stateResId = attrs.getAttributeNameResource(i);
+ switch (stateResId) {
+ case 0:
+ break;
+ case R.attr.drawable:
+ case R.attr.id:
+ // Ignore attributes from StateListDrawableItem and
+ // AnimatedStateListDrawableItem.
+ continue;
+ default:
+ states[j++] = attrs.getAttributeBooleanValue(i, false)
+ ? stateResId : -stateResId;
+ }
+ }
+ states = StateSet.trimStateSet(states, j);
+ return states;
+ }
+
StateListState getStateListState() {
return mStateListState;
}