javaandroidenumsdeclare-styleable

get stylable enum name from value


This is NOT the question asked a million times about enums.

I define the enums as part of styleable attribute (for a custom widget)

<declare-styleable name="ColorPickerPreference">
    <attr name="colorMode">
        <enum name="HSV"    value="0"/>
        <enum name="RGB"    value="1"/>
        <enum name="CMYK"   value="2"/>
    </attr>
</declare-styleable>

then I use it like this:

    <com.example.ColorPickerPreference
        android:key="@string/prefkey_color"
        android:title="@string/pref_color"
        android:summary="@string/pref_color_desc"
        custom:colorMode="RGB"/>

and in the preference constructor I would like to get the name "RGB".

public static enum ColorMode {
    RGB, HSV, CMYK
};

public ColorPickerPreference(Context context, AttributeSet attrs) {
    super(context, attrs);

    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ColorPickerPreference, 0, 0);
    try {
        String p = a.getString(R.styleable.ColorPickerPreference_colorMode);
        mColorMode = ColorMode.valueOf(p);
    } catch( Exception e ) {
        mColorMode = ColorMode.HSV;
    }

But this does not work, a.getString(...) returns "1" which is the value of "RGB" and I get an exception thrown mColorMode is assigned null because:

ColorMode.valueOf("1") == null

instead of

ColorMode.valueOf("RGB") == ColorMode.RGB

NOTE: I want to stress that ColorMode is not the enum that's causing the problem, the enum I need to get the name from is the one at the top of the question, declared in XML. Yes, they have the same names, but I cannot rely on them having the same numeric values.


Solution

  • (After wrong answer) I have no good answer, you have to program it out.

        int ordinal = a.getInt(R.styleable.ColorPickerPreference_colorMode);
        mColorMode = ColorMode.values().get(ordinal ^ 1);
    

    This above relies heavily on the ad hoc numbering in the XML, swaps bit 0, and gets the order of the enum.