以编程方式设置语言环境

新手上路,请多包涵

我的应用支持 3 种(很快 4 种)语言。由于几个语言环境非常相似,我想为用户提供在我的应用程序中更改语言环境的选项,例如,意大利人可能更喜欢西班牙语而不是英语。

有没有办法让用户在应用程序可用的语言环境中进行选择,然后更改使用的语言环境?我不认为为每个活动设置语言环境是一个问题,因为在基类中执行它是一项简单的任务。

原文由 Roland 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 446
2 个回答

对于仍在寻找此答案的人,因为 configuration.locale 已从 API 24 中弃用,您现在可以使用:

 configuration.setLocale(locale);

考虑到此方法的 minSkdVersion 是 API 17。

完整示例代码:

 @SuppressWarnings("deprecation")
private void setLocale(Locale locale){
    SharedPrefUtils.saveLocale(locale); // optional - Helper method to save the selected language to SharedPreferences in case you might need to attach to activity context (you will need to code this)
    Resources resources = getResources();
    Configuration configuration = resources.getConfiguration();
    DisplayMetrics displayMetrics = resources.getDisplayMetrics();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
        configuration.setLocale(locale);
    } else{
        configuration.locale=locale;
    }
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N){
        getApplicationContext().createConfigurationContext(configuration);
    } else {
        resources.updateConfiguration(configuration,displayMetrics);
    }
}

不要忘记,如果您使用正在运行的 Activity 更改语言环境,则需要重新启动它才能使更改生效。

编辑 2018 年 5 月 11 日

从 @CookieMonster 的帖子中可以看出,您可能会在较高 API 版本中保持语言环境更改时遇到问题。如果是这样,请将以下代码添加到您的 Base Activity(BaseActivity 扩展 AppCompatActivity / 其他活动),以便您在每次创建 Activity 时更新上下文区域设置:

 @Override
protected void attachBaseContext(Context base) {
     super.attachBaseContext(updateBaseContextLocale(base));
}

private Context updateBaseContextLocale(Context context) {
    String language = SharedPrefUtils.getSavedLanguage(); // Helper method to get saved language from SharedPreferences
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
        return updateResourcesLocale(context, locale);
    }

    return updateResourcesLocaleLegacy(context, locale);
}

@TargetApi(Build.VERSION_CODES.N_MR1)
private Context updateResourcesLocale(Context context, Locale locale) {
    Configuration configuration = new Configuration(context.getResources().getConfiguration());
    configuration.setLocale(locale);
    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    return context;
}

如果您使用它,请不要忘记在使用 setLocale(locale)

编辑 2020 年 4 月 7 日

您可能在 Android 6 和 7 中遇到问题,这是由于处理夜间模式时 androidx 库中的问题所致。为此,您还需要在基本活动中覆盖 applyOverrideConfiguration 并更新配置的区域设置,以防创建新的区域设置。

示例代码:

 @Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) {
        // update overrideConfiguration with your locale
        setLocale(overrideConfiguration) // you will need to implement this
    }
    super.applyOverrideConfiguration(overrideConfiguration);
}

原文由 Ricardo 发布,翻译遵循 CC BY-SA 4.0 许可协议

Appcompat 1.6.0-alpha04 及更高版本以来,有一种新方法可以让用户选择应用程序的默认语言。假设您有一个按钮,当用户单击它时应该将应用程序的语言更改为 _意大利语_:

 binding.button.setOnClickListener {
    val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags("it")
    AppCompatDelegate.setApplicationLocales(appLocale)
}

此外,要添加对旧设备的支持(< API 级别 32),请在您的 AndroidManifest.xml 文件的 <application> 标签内添加以下 service

 <service
  android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
  android:enabled="false"
  android:exported="false">
  <meta-data
    android:name="autoStoreLocales"
    android:value="true" />
</service>

确保拥有最新的 AppCompat 依赖项:


implementation 'androidx.appcompat:appcompat:1.6.0-alpha05'

参考: https ://developer.android.com/about/versions/13/features/app-languages

原文由 Roozbeh Zarei 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题