Как получить доступ к строкам ресурсов из перечисления ToString в Android? - программирование
Подтвердить что ты не робот

Как получить доступ к строкам ресурсов из перечисления 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() перечисления?

4b9b3361

Ответ 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;
    }
}