jsmith jsmith - 10 days ago 6
Android Question

Is there an Enum string resource lookup pattern for Android?

I have an enumeration where I need to display the values as localized strings. My current approach has been this:

public enum MyEnum {
VALUE1(R.string.VALUE1),
VALUE2(R.string.VALUE2),
.
.
VALUE10(R.string.VALUE10);

private int mResId = -1;

private MuEnum(int resId) {
mResId = resId;
}

public String toLocalizedString(Resource r) {
if (-1 != mResId) return (r.getString(mResId));
return (this.toString());
}
}


Is there any easier way to to do this? I'd love it if I could somehow lookup the resource based on the enumeration value name (i.e 'VALUE1').

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="VALUE1"/>My string</string>
<string name="VALUE2"/>My string 2</string>
.
.
<string name="VALUE10"/>My string 3</string>
</resources>


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

EDIT: Just for future reference, this is the solution that worked best for me:

public enum MyEnum {
VALUE1,
VALUE2,
.
.
VALUE10;

/**
* Returns a localized label used to represent this enumeration value. If no label
* has been defined, then this defaults to the result of {@link Enum#name()}.
*
* <p>The name of the string resource for the label must match the name of the enumeration
* value. For example, for enum value 'ENUM1' the resource would be defined as 'R.string.ENUM1'.
*
* @param context the context that the string resource of the label is in.
* @return a localized label for the enum value or the result of name()
*/
public String getLabel(Context context) {
Resources res = context.getResources();
int resId = res.getIdentifier(this.name(), "string", context.getPackageName());
if (0 != resId) {
return (res.getString(resId));
}
return (name());
}
}

Answer

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