web-dev-qa-db-ja.com

リソース名を表す変数を使用してR.stringのコンテンツにアクセスする

翻訳して表示する必要のある文字列がいくつかあります。それらの文字列は変数にあります。私は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);

...しかし、これはあまりうまくスケーリングしません。

助言がありますか?

翻訳されたバージョンを変数に保存する必要がありますか?

29
MyNameIsZero

このメソッドを使用して、文字列をint識別子に変換できます。

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

アクティビティをコンテキストパラメータ(またはその他のコンテキストインスタンス)として渡します。次に、getString()メソッドで通常どおり識別子を使用できます。

文字列から識別子への変換はリフレクションを使用するため、それほど高速ではない可能性があることに注意してください。慎重に使用してください。

49
 private String getStringResourceByName(String aString)
    {
      String packageName = context.getPackageName(); 
      int resId = getResources().getIdentifier(aString, "string", packageName);
      return getString(resId);
    }
5
ArK

もう1つできることは、文字列をリソースにマップすることです。そうすれば、文字列を変数に含めて(またはプログラムで作成して)、マップを使用してリソースIDを検索できます。

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

    // ...
}

アプリのローカライズ 異なる翻訳を使用している場合は、異なるリソースフォルダーを使用する必要があります。

3
Suragch

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)
        ""
    }
}
1