Is there an Enum string resource lookup pattern for Android?

Use static Application is always a bad practice, because not only it breaks Instant Run, but also this is against the decoupling principle of programming, thus makes modularization difficult to implement. Not to mention Android actually supports multiple Applications in a single process.

For this reason, I'd suggest define an inner class for the enum to be created in runtime, whenever locale might be changed.

enum Example {
    A(R.string.label_a),
    B(R.string.label_b);

    Example(@StringRes int label) { mLabel = label; }
    private @StringRes int mLabel;

    class Entry {
        private Context mContext;
        Entry(final Context context) { mContext = context; }
        @Override public String toString() { return mContext.getString(mLabel); }
    }
}

Then, build Example.Entry instance or array of Example.Entry to represent the localized version of the original enum.

Example.A.new Entry(context);

Arrays.stream(Example.values()).map(item -> item.new Entry(context)).toArray(Example.Entry[]::new)

I think what you have tried is good except you dont need to pass the resources argument to the enum every time you want to translate the enum.


Use the link to subclass the Application Class, then follow this approach.

Better Solution

import android.app.Application;

public enum MyEnum {

    VALUE1(R.string.VALUE1),
    VALUE2(R.string.VALUE2),
    .
    .
    VALUE10(R.string.VALUE10);

    private int resourceId;

    private MyEnum(int id)  {
        resourceId = id;
    }


    @Override
    public String toString() {

        return MyApplication.getApplicationContext().getString(resourceId);

    }

}

Then calling MyEnum.VALUEx will always give you the translated enum value, but be careful this might not be what you want always e.g you may have a raw query like this:

select * from Customer where userStatus = MyEnum.VALUEx.toString();

This may break your app, if you are storing the enum values as VALUE1, VALUE2... in db, so remember to use this MyEnum.VALUEx.name() when you dont want to use the translated value of your MyEnum.

select * from Customer where userStatus = MyEnum.VALUEx.name();

You can certainly look up a resource by its name using Resources.getIdentifier(). For instance, with the string resources you posted as an example, you can do this from an activity:

Resources res = getResources();
MyEnum e = MyEnum.VALUE1;
String localized = res.getString(res.getIdentifier(e.name(), "string", getPackageName()));

From a View, you'd have to change the last argument to getContext().getPackageName()


If you subclass your application class, you can have it as singleton ( see:http://androidcookbook.com/Recipe.seam?recipeId=1218 ) Once you got your singleton instance , you can use it in toLocalizedString() to get resource object and get rid of parameter:

 public String getString() {
    return YourApp.getInstance().getResources().getString(resId);
}

voila - now you have clean looking interface.