-1

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.

ilomambo
  • 8,290
  • 12
  • 57
  • 106
  • just take a look into android source oode how they implemen things like android:orientation or android:gravity – pskink Dec 17 '13 at 13:02
  • @pskink I looked at the source code. There is no consistent method, but as far as I understand it, the android coders do rely on numbering their resource enums (attr in XML) the same as their java constants (java source code). This is in my opinion an open door for bugs. – ilomambo Dec 17 '13 at 14:19
  • it cannot be done in a different way as in attrs.xml you define value= as an int not a string – pskink Dec 17 '13 at 14:27
  • @pskink but attr enums in XML have `name` as well as `value` and it stands to reason that there should be a way to retrieve the name too. – ilomambo Dec 17 '13 at 14:36
  • if the name was saved in the binary xml representation then yes in theory you could retrieve it somehow but i am afraid only integer value is saved – pskink Dec 17 '13 at 14:51
  • @pskink are you sure about that? A quick search got me to this https://code.google.com/p/apk-extractor/ which is an APK XML extractor, and at fist glance it seems to extract the attribute names from the APK. Of course I do not intend to go so far as to decompile the APK myself, just want to make sure there is no other way than to coordinate the same values among `enums`. – ilomambo Dec 17 '13 at 15:16
  • 1
    yes i saw it too, or similar called apkmanager, for sure when aapt builbs xml files to the binary form enums are not strings - unzip .apk and see res/layout/something.xml – pskink Dec 17 '13 at 16:23
  • 1
    also read this http://staticallytyped.wordpress.com/2011/04/16/android-custom-xml-attributes-and-views/ nice work – pskink Dec 17 '13 at 17:09

2 Answers2

0

You should try to implement a method to retrieve a value of your enum by int like it is described here : How to find an enum according to a value?

OR FOR LAZY PEOPLE :

public static enum ColorMode {
    RGB("1"), HSV("2"), CMYK("3")

    private String key;

    private static final Map<String, ColorMode> STRING_TO_ENUM = new HashMap<String, ColorMode>();

    static {
        for (ColorMode clrMode : ColorMode.values) {
            STRING_TO_ENUM.put(clrMode.key, clrMode);
        }
    }

    private ColorMode(String key) {
        this.key = key;
    }

    public ColorMode getByKey(String key) {
        return STRING_TO_ENUM.get(key);
    }   
};

Then you can use the method getByKey instead of the method valueOf to retrieve the value of the enum.

Community
  • 1
  • 1
Julien
  • 2,544
  • 1
  • 20
  • 25
  • It is not clear, in your post, how to apply it to enums declared as attributes, as i described. Please post the code that would do the trick. – ilomambo Dec 17 '13 at 12:58
  • I won't do the job. If you can't read 3 lines of Java from the other post, do it by yourself. – Julien Dec 17 '13 at 13:01
  • I read your post, you use there enums defined in java, not in XML. As it is, it does not work for my problem, and I don't know how to "translate" your code to make it work. So, if you know the answer, please say it explicitly. This is a help forum, not an ego forum. – ilomambo Dec 17 '13 at 13:12
  • @ilomambo i agree with Julien, he gave you an answer how ro map from int to enum, what else do you need? – pskink Dec 17 '13 at 13:26
  • Edited. I'm too kind. – Julien Dec 17 '13 at 13:29
  • @Julien Then it is my fault, because I did not explain my problem clear enough. The `enum ColorMode` in the java code is not my problem, I know how to get its names and values. My problem it the enums declared in XML, which may or may not have the same numeric value as ColorMode, that's why I want to rely only on the strings and not the values. I apologize if somehow I offended you. – ilomambo Dec 17 '13 at 13:33
  • @ilomambo The -1 for the answer actually IS an offend and yes, you did not expose your problem the right way. – Julien Dec 17 '13 at 13:38
  • 1
    `RGB("1"), HSV("0"), CMYK("2")` and `mColorMode = ColorMode.getByKey(p);` would do it. Specifying in the constructor the XML value. @Julien: I would edit the answer, remove the capitalized humor, and be welcome to answering in StackOverflow. – Joop Eggen Dec 17 '13 at 13:56
0

(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.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • your proposal does not compile, `valueOf()` requires a `String` argument, not `int`. Anyway, it seems to me that `R.styleable.ColorPickerPreference_colorMode` points to the attribute container, not its value. – ilomambo Dec 17 '13 at 13:15
  • I am ashamed, :). Changed answer into something useable. – Joop Eggen Dec 17 '13 at 13:50
  • Thanks, I was trying to avoid that. But I will use ad hoc correlated numbering if there is no other choice. – ilomambo Dec 17 '13 at 14:16