1

I've found a lot of posts on how to make a selector for custom boolean attributes (for example How to add a custom button state). But I couldn't find how to make a selector for enums or ints. Is it possible at all?

For example, I have custom enum attribute

<declare-styleable name="status_indicator">
    <attr name="status" format="enum">
        <enum name="value_offline" value="0"/>
        <enum name="value_away" value="1"/>
        <enum name="value_online" value="2"/>
    </attr>
</declare-styleable>

I want to use a background with a selector like

<selector xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:drawable="@drawable/status_offline" app:status="value_offline"/>
    <item android:drawable="@drawable/status_away" app:status="value_away"/>
    <item android:drawable="@drawable/status_online" app:status="value_online"/>
    <item>
        <shape android:shape="oval">
            <solid android:color="#ff00ff"/>
        </shape>
    </item>
</selector>

This code compiles, but selector always applies the first item like it has no conditions. I've read sources and found that item matching is made by compare of attribute sets. I assume that android framework can't build valid attribute set for the condition with enums or ints?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
porfirion
  • 1,619
  • 1
  • 16
  • 23

1 Answers1

0

I invented a workaround for enums - to declare fake boolean attributes like status_online, status_away, status_offline and place them into view state programmatically, depending on real "state" attribute value. But it looks very ugly and can't solve problem with indefinite ints (definite set of ints also can be replaced by fake boolean attributes)

Realization of workaround:

<declare-styleable name="status_indicator">
    <attr name="status_offline" format="boolean"/>
    <attr name="status_away" format="boolean"/>
    <attr name="status_online" format="boolean"/>
    <attr name="status" format="enum">
        <enum name="value_offline" value="0"/>
        <enum name="value_away" value="1"/>
        <enum name="value_online" value="2"/>
    </attr>
</declare-styleable>

and

@Override
public int[] onCreateDrawableState(int extraSpace) {
    final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
    switch (status) {
        case STATUS_ONLINE:
            mergeDrawableStates(drawableState, STATE_STATUS_ONLINE);
            break;
        case STATUS_AWAY:
            mergeDrawableStates(drawableState, STATE_STATUS_AWAY);
            break;
        case STATUS_OFFLINE:
            mergeDrawableStates(drawableState, STATE_STATUS_OFFLINE);
            break;
        default:
            break;
    }

    return drawableState;
}

Then selector layout should look tike

<selector xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:drawable="@drawable/status_offline" app:status_offline="true"/>
    <item android:drawable="@drawable/status_away" app:status_away="true"/>
    <item android:drawable="@drawable/status_online" app:status_online="true"/>
    <item>
        <shape android:shape="oval">
            <solid android:color="#ff00ff"/>
        </shape>
    </item>
</selector>
porfirion
  • 1,619
  • 1
  • 16
  • 23