因此,无论设备/应用程序当前的语言环境设置如何,我都希望在多个语言环境中获取String的值。我该怎么办?
基本上我需要的是功能getString(int id, String locale)
而不是功能getString(int id)
我该怎么办?
谢谢
因此,无论设备/应用程序当前的语言环境设置如何,我都希望在多个语言环境中获取String的值。我该怎么办?
基本上我需要的是功能getString(int id, String locale)
而不是功能getString(int id)
我该怎么办?
谢谢
ResourceBundle
应该是指资产?还是他们可以访问我们的res文件夹?
getString(R.strings.text)
,将获得用户语言中的字符串(如果用户语言是没有文件夹,则为默认值)
Answers:
注意如果您的最低API为17+,请直接跳至此答案的底部。否则,请继续阅读...
注意如果使用的是App Bundle,则需要确保禁用语言拆分或动态安装其他语言。请参阅https://stackoverflow.com/a/51054393。如果不这样做,它将始终使用后备。
如果您有用于不同语言环境的各种res文件夹,则可以执行以下操作:
Configuration conf = getResources().getConfiguration();
conf.locale = new Locale("pl");
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Resources resources = new Resources(getAssets(), metrics, conf);
String str = resources.getString(id);
另外,您也可以使用@jyotiprakash指向的方法重新开始活动。
注意Resources
像这样调用构造函数会在Android内部进行一些更改。您必须使用原始语言环境调用构造函数,以使事情恢复原样。
编辑从特定语言环境中检索资源的方法略有不同(且更为简洁):
Resources res = getResources();
Configuration conf = res.getConfiguration();
Locale savedLocale = conf.locale;
conf.locale = desiredLocale; // whatever you want here
res.updateConfiguration(conf, null); // second arg null means don't change
// retrieve resources from desired locale
String str = res.getString(id);
// restore original locale
conf.locale = savedLocale;
res.updateConfiguration(conf, null);
从API级别17开始,您应该使用conf.setLocale()
而不是直接设置conf.locale
。如果您恰巧在从右到左和从左到右的语言环境之间进行切换,这将正确更新配置的布局方向。(布局方向在17中介绍。)
创建新Configuration
对象(如@Nulano在评论中建议的那样)没有任何意义,因为调用updateConfiguration
将更改通过调用获得的原始配置res.getConfiguration()
。
getString(int id, String locale)
如果您要为区域设置加载多个字符串资源,我会毫不犹豫地将其捆绑为一个方法。更改语言环境(使用任何一种方法)都要求框架进行大量重新绑定所有资源的工作。最好一次更新区域设置,检索所需的所有内容,然后再设置区域设置。
编辑(感谢@Mygod):
如果您的最低API级别为17+,则有更好的方法,如另一个线程上的此答案所示。例如,您可以使用以下Resource
对象创建多个对象,每个对象分别用于所需的语言环境:
@NonNull Resources getLocalizedResources(Context context, Locale desiredLocale) {
Configuration conf = context.getResources().getConfiguration();
conf = new Configuration(conf);
conf.setLocale(desiredLocale);
Context localizedContext = context.createConfigurationContext(conf);
return localizedContext.getResources();
}
然后,只需Resource
从此方法返回的本地化对象中检索所需的资源即可。检索资源后,无需重置任何内容。
getResources().getConfiguration()
吗?根据GrepCode,它返回存储在资源中的本地实例。之后更改语言环境字段可能是Android感到困惑的真正原因。您可能应该conf = new Configuration(conf);
在第一行和第二行之间执行(克隆返回的配置)。
Resources
构造函数的源代码,您将看到创建这样的新Resources
对象会更改流程资产(显然是单例)中的内容。一旦我意识到需要重新设置一切,我就不必费心寻找确切的原因。构造新Resources
对象的另一种方法(也许更清洁)是resources.updateConfiguration(conf, null)
在更改区域设置后调用。
这是Ted Hopp描述的方法的组合版本。这样,该代码可用于任何Android版本:
public static String getLocaleStringResource(Locale requestedLocale, int resourceId, Context context) {
String result;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { // use latest api
Configuration config = new Configuration(context.getResources().getConfiguration());
config.setLocale(requestedLocale);
result = context.createConfigurationContext(config).getText(resourceId).toString();
}
else { // support older android versions
Resources resources = context.getResources();
Configuration conf = resources.getConfiguration();
Locale savedLocale = conf.locale;
conf.locale = requestedLocale;
resources.updateConfiguration(conf, null);
// retrieve resources from desired locale
result = resources.getString(resourceId);
// restore original locale
conf.locale = savedLocale;
resources.updateConfiguration(conf, null);
}
return result;
}
用法示例:
String englishName = getLocaleStringResource(new Locale("en"), R.string.name, context);
注意
如原始答案中所述,用单个配置更改和多个resource.getString()调用替换上述代码的多个调用可能会更有效。
根据以上答案,这些功能很棒但有点复杂。试试这个简单的功能:
public String getResStringLanguage(int id, String lang){
//Get default locale to back it
Resources res = getResources();
Configuration conf = res.getConfiguration();
Locale savedLocale = conf.locale;
//Retrieve resources from desired locale
Configuration confAr = getResources().getConfiguration();
confAr.locale = new Locale(lang);
DisplayMetrics metrics = new DisplayMetrics();
Resources resources = new Resources(getAssets(), metrics, confAr);
//Get string which you want
String string = resources.getString(id);
//Restore default locale
conf.locale = savedLocale;
res.updateConfiguration(conf, null);
//return the string that you want
return string;
}
然后简单地调用它: String str = getResStringLanguage(R.string.any_string, "en");
快乐的代码:)