简体   繁体   English

使用变量访问R.string的内容以表示资源名称

[英]Accessing contents of R.string using a variable to represent the resource name

I have a few strings which I need to translate and display. 我有一些字符串需要翻译和显示。 Those strings are in variables. 这些字符串是变量。 I have the translation in the strings.xml file. 我在strings.xml文件中有翻译。

I want to display the "translated version" of the string. 我想显示字符串的“翻译版本”。 For example, inside an Activity: 例如,在Activity中:

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

In the strings file I have the definition 在字符串文件中我有定义

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

If I used something like this: 如果我使用这样的东西:

nameDisplay.setText(R.string.KnownName);

it would work. 它会奏效。 But in my case, the name is stored in a variable so I do not know what to do in order for the setText method to function properly. 但在我的情况下,名称存储在一个变量中,所以我不知道该怎么做才能使setText方法正常运行。

My current workaround is 我目前的解决方法是

String translation = ""

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

nameDisplay.setText(translation);

... but this does not scale very well. ......但这不能很好地扩展。

Any suggestions? 有什么建议么?

Should I store the translated version in the variable? 我应该将翻译版本存储在变量中吗?

You can use the method to convert string into int identifier: 您可以使用该方法将字符串转换为int标识符:

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

Pass in an activity as context parameter (or any other Context instance). 将活动作为上下文参数(或任何其他上下文实例)传递。 Then you can use the identifier as usual with getString() method. 然后您可以像往常一样使用getString()方法使用标识符。

Note that conversion from string to identifier uses reflection and thus can be not that fast, so use carefully. 请注意,从字符串到标识符的转换使用反射,因此可能不那么快,因此请谨慎使用。

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

Another thing you can do is map the string to the resource. 您可以做的另一件事是将字符串映射到资源。 That way you can have the string in a variable (or build it programmatically) and then use the map to look up the resource id. 这样,您可以将字符串放在变量中(或以编程方式构建它),然后使用映射来查找资源ID。

Example

strings.xml strings.xml中

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

Code

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

    // ...
}

Note 注意

If you are localizing your app with different translations, then you should be using different resource folders. 如果您使用不同的翻译本地化您的应用程序 ,那么您应该使用不同的资源文件夹。

As a Kotlin extension, ArK's answer could be written the following way. 作为Kotlin扩展,ArK的答案可以用以下方式编写。 It also catches an exception when you give it an unknown key. 当你给它一个未知的密钥时,它也会捕获异常。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM