Как получить доступ к строкам ресурсов из перечисления ToString в Android?
В моем приложении у меня есть Spinner, который заполняется из перечисления:
ArrayAdapter<myEnum> enumAdapter = new ArrayAdapter<Stroke> (parentActivity.getApplicationContext(), R.layout.simple_spinner_item, myEnum.values());
enumAdapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item);
enumSpinner.setAdapter(strokeAdapter);
Это использует переопределение метода enum toString()
, чтобы получить дружественное имя для значений перечисления, отображаемых в Spinner
. В настоящее время в моем перечислении есть строки, жестко закодированные для дружественных имен, но я бы хотел переместить их в strings.xml
для поддержки локализации.
Однако toString не имеет доступа к Context
, поэтому я не уверен, как разрешить идентификаторы ресурсов.
Есть ли способ получить локализованные строки в методе toString() перечисления?
Ответы
Ответ 1
Если я это правильно понимаю, реальный вопрос заключается в том, как получить Context
из вашего enum
, чтобы вы могли вызвать Context.getString()
, чтобы получить локализованные версии строк, которые вам нужны.
Одним из подходов было бы установить статическую переменную-член типа Context
в вашем приложении onCreate()
метод, описанный в этом ответе. Идея здесь в том, что каждый раз, когда ваше приложение создается или воссоздается, вы будете придерживаться контекста приложения в переменной, к которой легко добраться.
Затем передайте идентификатор ресурса в конструкторе ваших значений перечисления и используйте контекст в вашем методе toString()
.
Например:
public enum Example {
HELLO(R.string.hello),
WORLD(R.string.world);
private int mResourceId;
private Example(int id) {
mResourceId = id;
}
@Override
public String toString() {
return App.getContext().getString(mResourceId);
}
}
Ответ 2
@Override public String toString() { return App.getContext(). getString (id); }
Важно, чтобы ваш класс enum не имел связей с вашей деятельностью, потому что если вы хотите использовать его в другом приложении, то вы не сможете, если ссылаетесь на статический контекст.
Таким образом, лучшим способом было бы вернуть идентификатор ресурса строки обратно в действие, а затем позволить активности захватывать строку, используя идентификатор из своих.
Итак, из вашего класса enum у вас будет метод, который выглядит примерно так:
public int getResourceId()
{
return resourceId;
}
Тогда в вашей деятельности я бы создал список, содержащий arraylist:
final List<String> enumList = new ArrayList<String>();
for ( final MyEnum status : MyEnum.values() )
{
enumList.add( getString( status.getResourceId() ) );
}
Затем вы можете использовать enumList с вашим ArrayAdapter, Bingo:)
Итак, теперь у вас нет связей с классом enum, и поэтому, если вы создадите другое приложение, которое должно использовать тот же класс перечисления, качество которого вам легко сделать.
Ответ 3
Использование статического приложения - это всегда плохая практика, потому что не только он прерывает Instant Run, но и это противоречит принципу развязки, что затрудняет реализацию модуляции. Не говоря уже о том, что Android фактически поддерживает несколько приложений в одном процессе.
По этой причине я бы предложил определить внутренний класс для перечисления в качестве записей адаптера.
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 final Context mContext;
Entry(final Context context) { mContext = context; }
@Override public String toString() { return mContext.getString(mLabel); }
}
}
Затем постройте массив Example.Entry для адаптера.
Arrays.stream(Example.values()).map(item -> item.new Entry(context)).toArray(Example.Entry[]::new)
Ответ 4
Я не уверен на 100%, я понимаю, о чем вы спрашиваете.
Есть ли способ получить локализованные строки в методе toString() перечисления?
Вы можете, конечно, @Override
метод toString()
внутри вашего myEnum
изменить способ его отображения:
public enum myEnum {
ONE("1"),
TWO("2");
private String pretty;
private myEnum(String pretty) {
this.pretty = pretty;
}
@Override
public String toString() {
// you can localise this string somehow here
return pretty;
}
}