有一个Android的Enumstring资源查找模式?

我有一个枚举,我需要显示为本地化的string的值。 我目前的做法是这样的:

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(Resources r) { if (-1 != mResId) return (r.getString(mResId)); return (this.toString()); } } 

有没有更简单的方法来做到这一点? 我很喜欢它,如果我能以某种方式查找基于枚举值名称(即“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> 

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

编辑:仅供将来参考,这是最适合我的解决scheme:

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

Solutions Collecting From Web of "有一个Android的Enumstring资源查找模式?"

您当然可以使用Resources.getIdentifier()按名称查找资源。 例如,以您发布的string资源为例,您可以从一个活动中执行此操作:

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

从视图中,你必须改变最后一个参数getContext().getPackageName()

我认为你已经尝试的是好的,除非你不需要将资源parameter passing给枚举每次你想要翻译枚举。


使用链接来inheritance应用程序类,然后按照这个方法。

更好的scheme

 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); } } 

然后调用MyEnum.VALUEx将永远给你的翻译枚举值但要小心这可能不是你想要的总是例如,你可能有一个像这样的原始查询:

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

这可能会破坏您的应用程序,如果您要将枚举值存储为db中的VALUE1,VALUE2 …,那么当您不想使用MyEnum的转换值时,请记住使用此MyEnum.VALUEx.name()

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

如果你inheritance你的应用程序类,你可以把它作为单例(见:http://androidcookbook.com/Recipe.seam?recipeId = 1218)一旦你得到了你的单例实例,你可以在toLocalizedString()中使用它来获取资源对象和摆脱参数:

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

瞧 – 现在你有干净的外观界面。

使用静态应用程序总是一个不好的做法,因为它不仅打破了Instant Run,而且这也违背了编程的解耦原则,从而使得模块化难以实现。 更何况Android实际上在单个进程中支持多个应用程序。

出于这个原因,我会build议定义一个内部类的枚举在运行时创build,只要区域设置可能会改变。

 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); } } } 

然后,构buildExample.Entry的Example.Entry实例或数组来表示原始枚举的本地化版本。

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

首先创build新的类:

 import android.app.Application; public class MyApplication extends Application { private static MyApplication singleton; public static MyApplication getInstance(){ return singleton; } @Override public void onCreate() { super.onCreate(); singleton = this; } } 

现在在AndroidManifest.xml中添加对应用程序类的引用:

 <application ... android:name="com.yourPackageName.application.MyApplication "> 

接下来创build你的枚举。 性别枚举示例:

 public enum Gender { MALE(0, R.string.male), FEMALE(1, R.string.female); private Integer resourceId; private Integer index; private static final Map<Integer, Gender> lookupIndex = new HashMap<Integer, Gender>(); private static final Map<Integer, Gender> lookupResourceId = new HashMap<Integer, Gender>(); private static final Map<String, Gender> lookupTranslation = new HashMap<String, Gender>(); static { for (Gender g : values()) { lookupIndex.put(g.getIndex(), g); lookupResourceId.put(g.getResourceId(), g); lookupTranslation.put(g.toString(), g); } } private Gender(Integer index, Integer displayText) { this.resourceId = displayText; this.index = index; } public Integer getIndex() { return this.index; } public Integer getResourceId() { return this.resourceId; } public static Gender findByIndex(Integer index) { return lookupIndex.get(index); } public static Gender findByResourceId(Integer id) { return lookupResourceId.get(id); } public static Gender findByTranslationText(String text) { return lookupTranslation.get(text); } @Override public String toString() { return MyApplication.getInstance().getResources().getString(this.resourceId); }} 

现在,您可以使用请求的查找模式:

 // by index Gender male = Gender.findByIndex(0); // by translation String femaleTranslated = context.getResources().getString(R.string.female); Gender gender = Gender.findByTranslationText(femaleTranslated); // by id Gender gender = Gender.findByResourceId(R.string.female); 

特别感谢艾哈迈德Yüksektepe