Доступ к содержимому R.string с помощью переменной для представления имени ресурса - PullRequest
27 голосов
/ 21 августа 2010

У меня есть несколько строк, которые мне нужно перевести и отобразить. Эти строки находятся в переменных. У меня есть перевод в файле strings.xml.

Я хочу отобразить «переведенную версию» строки. Например, внутри действия:

String name = "Water";
TextView nameDisplay = new TextView(this).
nameDisplay.setText(name);

В файле строк у меня есть определение

<string name="Water">French word for Water</string>

Если бы я использовал что-то вроде этого:

nameDisplay.setText(R.string.KnownName);

это будет работать. Но в моем случае имя хранится в переменной, поэтому я не знаю, что делать, чтобы метод setText работал правильно.

Мой текущий обходной путь -

String translation = ""

if(name == "Water") {
  translation = getString(R.string.Water);
}
else {
  ...
}

nameDisplay.setText(translation);

... но это не очень хорошо масштабируется.

Есть предложения?

Должен ли я хранить переведенную версию в переменной?

Ответы [ 4 ]

49 голосов
/ 22 августа 2010

Вы можете использовать метод для преобразования строки в идентификатор int:

public static int getStringIdentifier(Context context, String name) {
    return context.getResources().getIdentifier(name, "string", context.getPackageName());
}

Передать действие в качестве параметра контекста (или любого другого экземпляра контекста).Затем вы можете использовать идентификатор как обычно с методом getString ().

Обратите внимание, что преобразование из строки в идентификатор использует отражение и, следовательно, может быть не таким быстрым, поэтому используйте его осторожно.

5 голосов
/ 25 августа 2011
 private String getStringResourceByName(String aString)
    {
      String packageName = context.getPackageName(); 
      int resId = getResources().getIdentifier(aString, "string", packageName);
      return getString(resId);
    }
2 голосов
/ 29 ноября 2017

Еще одна вещь, которую вы можете сделать, это сопоставить строку с ресурсом.Таким образом, вы можете поместить строку в переменную (или построить ее программно), а затем использовать карту для поиска идентификатора ресурса.

Пример

strings.xml

<string name="water_english">water</string>
<string name="water_spanish">agua</string>
<string name="water_chinese">水</string>
<string name="water_mongolian">ᠤᠰᠥ</string>

Код

public class MainActivity extends AppCompatActivity {

    private Map<String, Integer> stringForResourceIdMap = createMap();

    private Map<String, Integer> createMap() {
        Map<String, Integer> result = new HashMap<>();

        result.put("water_english", R.string.water_english);
        result.put("water_spanish", R.string.water_spanish);
        result.put("water_chinese", R.string.water_chinese);
        result.put("water_mongolian", R.string.water_mongolian);

        return result;
    }

    private String getMyStringResource(String lookupString) {
        int resourceId = stringForResourceIdMap.get(lookupString); // R.string.xxx
        return getString(resourceId);
    }

    // ...
}

Примечание

Если вы локализуете приложение с разными переводами, то вы должны использовать разные папки ресурсов.

1 голос
/ 10 февраля 2019

Как расширение Kotlin, ответ ArK можно записать следующим образом. Также выдается исключение, когда вы даете ему неизвестный ключ.

fun Context.getStringWithResKey(nameResKey: String): String {
    val resId = resources.getIdentifier(nameResKey, "string", packageName)
    return try {
        getString(resId)
    } catch (e: Exception) {
        Log.e(this.javaClass.simpleName, "Couldn't find string value for key '$nameResKey'", e)
        ""
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...