因此,无论设备/应用程序的当前语言环境设置如何,我都想在多个语言环境中获取字符串的值。我该怎么做?
基本上我需要的是一个功能getString(int id, String locale)
而不是getString(int id)
我怎么能那样做?
谢谢
因此,无论设备/应用程序的当前语言环境设置如何,我都想在多个语言环境中获取字符串的值。我该怎么做?
基本上我需要的是一个功能getString(int id, String locale)
而不是getString(int id)
我怎么能那样做?
谢谢
注意如果您的最低 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
然后只需从该方法返回的本地化对象中检索您喜欢的资源。检索资源后,无需重置任何内容。
这是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);
笔记
如原始答案中所述,将上述代码的多个调用替换为单个配置更改和多个 resources.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");
快乐的代码:)
将此 Kotlin 扩展函数放入您的代码中并像这样使用它:
getLocaleStringResource(Locale.ENGLISH,R.string.app_name)
fun Context.getLocaleStringResource(
requestedLocale: Locale?,
resourceId: Int,
): String {
val result: String
val config =
Configuration(resources.configuration)
config.setLocale(requestedLocale)
result = createConfigurationContext(config).getText(resourceId).toString()
return result
}
例如可以这样做吗?
String stringFormat = getString(stringId);
String string = String.format(Locale.ENGLISH, stringFormat, 6);