以编程方式设置区域设置 [英] Set Locale programmatically

查看:132
本文介绍了以编程方式设置区域设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My app supports 3 (soon 4) languages. Since several locales are quite similar I'd like to give the user the option to change locale in my application, for instance an Italian person might prefer Spanish over English.

用户是否可以从应用程序可用的语言环境中进行选择,然后更改使用的语言环境?我认为为每个Activity设置区域设置不是问题,因为这是在基类中执行的简单任务.

Is there a way for the user to select among the locales that are available for the application and then change what locale is used? I don't see it as a problem to set locale for each Activity since it is a simple task to perform in a base class.

推荐答案

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

For people still looking for this answer, since configuration.locale was deprecated from API 24, you can now use:

configuration.setLocale(locale);

请注意,此方法的minSkdVersion是API 17.

Take in consideration that the minSkdVersion for this method is 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更改语言环境,则需要重新启动它才能使更改生效.

Don't forget that, if you change the locale with a running Activity, you will need to restart it for the changes to take effect.

编辑2018年5月11日

从@CookieMonster的帖子开始,您可能在将语言环境更改保留在更高版本的API中时遇到问题.如果是这样,请将以下代码添加到基本活动中,以便在每次创建活动时更新上下文区域设置:

As from @CookieMonster's post, you might have problems keeping the locale change in higher API versions. If so, add the following code to your Base Activity so that you update the context locale on every Activity creation:

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

如果使用此选项,请在使用setLocate(locale)

If you use this, don't forget to save the language to SharedPreferences when you set the locale with setLocate(locale)

编辑2020年4月7日

您可能在Android 6和7中遇到问题,这是由于在处理夜间模式时androidx库中的问题引起的.为此,您还需要在基本活动中覆盖applyOverrideConfiguration并更新配置的语言环境,以防创建新的语言环境.

You might be experiencing issues in Android 6 and 7, and this happens due to an issue in the androidx libraries while handling the night mode. For this you will also need to override applyOverrideConfiguration in your base activity and update the configuration's locale in case a fresh new locale one is created.

示例代码:

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

这篇关于以编程方式设置区域设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆