Q1: Has anyone managed to get custom string/enum attribute working in xml selectors? I got a boolean attribute working by following [1], bu
Sorry, you cannot create custom drawables in xml : https://groups.google.com/d/msg/android-developers/glpdi0AdMzI/LpW4HGMB3VIJ
Q1:
When you open the source-code of StateListDrawable.java, you can see this piece of code in the inflate
method that reads the drawable xml selector:
https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/graphics/java/android/graphics/drawable/StateListDrawable.java
...
for (i = 0; i < numAttrs; i++) {
final int stateResId = attrs.getAttributeNameResource(i);
if (stateResId == 0) break;
if (stateResId == com.android.internal.R.attr.drawable) {
drawableRes = attrs.getAttributeResourceValue(i, 0);
} else {
states[j++] = attrs.getAttributeBooleanValue(i, false)
? stateResId
: -stateResId;
}
}
...
attrs
are the attributes of each <item>
element in the <selector>
.
In this for-loop it gets the android:drawable
, the various android:state_xxxx
and custom app:xxxx
attributes. All but the android:drawable
attributes seem to be interpreted as booleans only: attrs.getAttributeBooleanValue(....)
is called.
I think this is the answer, based on the source code:
You can only add custom boolean attributes to your xml, not any other type (including enums).
Q2:
I'm not sure why the state is merged only if it is specifically set to true. I would suspect the code should have looked like this instead:
private static final int[] MAKE_DARK_BG_SET = { R.attr.make_dark_background };
private static final int[] NOT_MAKE_DARK_BG_SET = { -R.attr.make_dark_background };
....
....
@Override
protected int[] onCreateDrawableState(int extraSpace) {
Log.i(TAG, "onCreateDrawableState()");
final int[] drawableState = super.onCreateDrawableState(extraSpace + 2);
mergeDrawableStates(drawableState, mMakeDarkBg? MAKE_DARK_BG_SET : NOT_MAKE_DARK_BG_SET);
//mergeDrawableStates(drawableState, STR_ATTR_ID);
return drawableState;
}
Q1:
I haven't tried this myself, but:
Have you tried placing your @color/custom_button_text_color.xml
in the drawable
folder? (Just to be sure, there's a bit of folder magic here and there in Android and I'm not sure about this one.)
Q2:
There are two use cases for state sets. One is to explicitly declare selectors for stateful drawables programmatically. In this case, for selectors, you need to be able to tell Android to use this drawable if an attribute is not set. To express this, you can include the negated criteria (preceded by a minus sign) in the int[]
.
While this is barely mentioned anywhere in the context of selector criteria, it is never mentioned for drawable states themselves (aka the representation of the drawable's state). So one is definitely on the safe side if one does not include negated state IDs in the set; the provided Android implementations also do not includde them.