Страницы

Поиск по вопросам

пятница, 13 декабря 2019 г.

Программное получение строки по ее имени в файле ресурсов

#java #android #строки


Приветствую, такой вопрос, у меня есть 50 значений строк c именами name1, name2,
и т.д и разным текстом, хранятся в файле String.xml. Сначала в textView показывается
1 строка с именем name1, по нажатию кнопки, textView показывает name2, и т.д. Сейчас
это сделано примитивным способом:
Есть переменная Count, при нажатии кнопки Count увеличивается на 1 и сравнивается
значение

 switch (Count) {
                    case 1:
                         textView.setText(R.string.name1);
                        break;
                    case 2:
                         textView.setText(R.string.nаme2);
                        break;
                     ...............


Но так как значений 50, это делать глупо.

Можно ли организовать что-то типа такого:
textView.setText(R.string.nаme+count);     ?

Или есть решение попроще?
    


Ответы

Ответ 1



Храни свои 50 строк в массиве строк strings.xml, в виде Mercury Venus Earth Mars Обращение к массиву в коде производится вызовом метода getResources().getStringArray(R.array.your_array); который возвращает массив строк

Ответ 2



Прописывать нужные строки в коде и хранить их в памяти не самый лучший вариант. Вы можете получить содержимое любого ресурса по его имени,в том числе сформированного динамически, через метод getIdentifier() SDK, для которого в качестве параметров необходимо указать: само имя ресурса, тип ресурса (string, dimen, color, drawable, id и тд.), имя пакета. Например, чтобы получить строковый ресурс с именем name1: package com.example.myapp; ... int stringNumber = 1; int stringID = getResources().getIdentifier("name" + stringNumber, "string", "com.example.myapp"); TextView text = (TextView)findViewById(R.id.text); text.setText(stringID); names.xml String number 1 String number 2 В TextView будет выведено: "String number 1" Стоит заметить, что вы можете поместить свои строки не в strings.xml, а в отдельный файл, какой-нибудь names.xml, как в моем примере, с аналогичной структурой и поместить этот файл в папку res/values/, чтобы не хранить их вместе с строковыми ресурсами самого приложения и удобнее было редактировать. PS: у вас будет свое имя пакета, указанное после оператора package а не com.example.myapp Альтернативным решением может быть парсинг JSON или XML, SDK предоставляет инструменты для этого.

Ответ 3



Альтернативное решение Как я уже отметил в комментарии, хранить одновременно все 50 строк в памяти может быть неэффективно, да и код переписывать при появлении новых строк - неправильно. Решение должно быть таким, чтобы при добавлении и изменении строк не приходилось переписывать код. Поэтому предлагаю хранить строки в текстовом файле и написать метод, который загружает строку по ее номеру. Тогда все 50 переменных вообще исчезают из вашего кода и памяти приложения, а остается textView.setText(loadString(i)); Прямое решение Положите строки в массив или список и обращайтесь к ним по индексу. Вот на английском SO я об этом отвечал: https://stackoverflow.com/a/30864495/2790048 Напрямую обращаться к переменной, имея строку с ее именем, нельзя. Это возможно с помощью пакета Reflexion, но это непроизводительно и чревато ошибками, да и не требуется в данном случае. Можно добавить все строки или объекты любого другого класса в параметризованный список: int initialCapacity = 50; List stringsList = new ArrayList(initialCapacity); for (int i = 0; i < 10; i++) { stringsList.add(loadString(i)); } Если количество совершенно точно не меняется в ходе работы программы, можно использовать массив: String[] stringsArray = new String[10]; for (int i = 0; i < lists.length; i ++) { stringsArray[i] = loadString(i); } Теперь к ним удобно обращаться: textView.setText(stringsList.get(i)); textView.setText(stringsArray[i]);

Ответ 4



Для этого можно использовать Reflection, чтобы найти значение свойства R.string динамическим образом. try { String text = (String) R.string.class.getField("name" + count).get(null); textView.setText(text); } catch (Exception e) { // R.string.name{count} либо не существует, либо не является строком. } Как @Nick Volynkin отметил в коментарии, есть большая вероятность, что другое решение существует лучше хранения 50 строк в strings.xml. Если возможно, лучше найти способ кроме Reflection, потому что Reflection выполняется медленно и иногда может быть немного опасным. Но я не знаю детали о вашем проекте, так что не знаю, что ещё рекомендовать вам.

Ответ 5



getResources().getString(R.string.MyString) Это для отдельной строки, но если вы задали Массив в XML файле, то можно вызвать его getResources().getStringArray(R.string.MyArrayString)

Комментариев нет:

Отправить комментарий