以编程方式更改语言(Android N 7.0-API 24) [英] Change language programmatically (Android N 7.0 - API 24)

查看:126
本文介绍了以编程方式更改语言(Android N 7.0-API 24)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码在我的应用中设置特定的语言.语言将保存到应用程序的SharedPreferences中. 它在API级别23上也能完美运行.在Android N SharedPreferences上也能很好地工作,它返回正确的语言代码字符串,但不会更改语言环境(设置手机的默认语言) ).有什么问题吗?

I'm using the following code to set specific language in my app. Language is saved into SharedPreferences within the app. And it works perfectly up to API level 23. With Android N SharedPreferences works well too, it returns the correct language code-string, but it does not change the locale (sets default language of the phone). What could be wrong?

更新1:当我在res.updateConfiguration(config, dm)之后立即使用Log.v("MyLog", config.locale.toString());时,它会返回正确的语言环境,但应用程序的语言未更改.

Update 1: When I use Log.v("MyLog", config.locale.toString()); immediately after res.updateConfiguration(config, dm) it returns correct locale, but language of the app does not changed.

更新2:我还提到过,如果我更改语言环境然后重新启动活动(使用新的意图并在旧的意图上完成),它将正确地更改语言,甚至在显示正确的语言之后回转.但是,当我关闭该应用程序并再次打开它时,我得到了默认语言.很奇怪.

Update 2: I also mentioned that if I change locale and then restart the activity (using new intent and finish on the old one), it changes the language properly, it even shows correct language after rotation. But when I close the app and open it again, I get default language. It's weird.

public class ActivityMain extends AppCompatActivity {

    //...
    @Override
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);
        // Set locale
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        String lang = pref.getString(ActivityMain.LANGUAGE_SAVED, "no_language");
        if (!lang.equals("no_language")) {
            Resources res = context.getResources();
            Locale locale = new Locale(lang);
            Locale.setDefault(locale);
            DisplayMetrics dm = res.getDisplayMetrics();
            Configuration config = res.getConfiguration();
            if (Build.VERSION.SDK_INT >= 17) {
                config.setLocale(locale);
            } else {
                config.locale = locale;
            }
        }
        res.updateConfiguration(config, dm);

        setContentView(R.layout.activity_main);
        //...
    } 
    //... 
}

更新3: 答案也在这里: https://stackoverflow.com/a/40849142/3935063

推荐答案

创建一个扩展ContextWrapper的新类

Create a new class extends ContextWrapper

public class MyContextWrapper extends ContextWrapper {
    public MyContextWrapper(Context base) {
        super(base);
    }

    @TargetApi(Build.VERSION_CODES.N)
    public static ContextWrapper wrap(Context context, Locale newLocale) {
        Resources res = context.getResources();
        Configuration configuration = res.getConfiguration();

        if (VersionUtils.isAfter24()) {
            configuration.setLocale(newLocale);

            LocaleList localeList = new LocaleList(newLocale);
            LocaleList.setDefault(localeList);
            configuration.setLocales(localeList);

            context = context.createConfigurationContext(configuration);

        } else if (VersionUtils.isAfter17()) {
            configuration.setLocale(newLocale);
            context = context.createConfigurationContext(configuration);

        } else {
            configuration.locale = newLocale;
            res.updateConfiguration(configuration, res.getDisplayMetrics());
        }

        return new ContextWrapper(context);
    }
}

覆盖活动的attachBaseContext方法

override Activity's attachBaseContext method

@Override
protected void attachBaseContext(Context newBase) {
    Locale languageType = LanguageUtil.getLanguageType(mContext);
    super.attachBaseContext(MyContextWrapper.wrap(newBase, languageType));
}

完成活动并重新开始,新的语言环境将生效.

finish the activity and start it again,new locale will become effective.

演示: https://github.com/fanturbo/MultiLanguageDemo

这篇关于以编程方式更改语言(Android N 7.0-API 24)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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