以编程方式更改语言(Android N 7.0-API 24) [英] Change language programmatically (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屋!