我试图根据用户的输入更改应用程序的语言。我尝试使用此代码来更改应用程序的语言,并且它的工作非常好。
public void setLocale(String lang) {
myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
Intent refresh = new Intent(MainActivity.this, MainActivity.class);
startActivity(refresh);
}
但问题是app必须重新启动/刷新才能重新加载资源。
答案 0 :(得分:1)
是的,您的代码是正确的,如果您需要而不刷新应用程序
然后在应用课程中,您需要在onCreate()
方法中调用此方法
String languageSelected = "en";//selected language
Locale myLocale = new Locale(languageSelected);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
getActivity().onConfigurationChanged(conf);//Call this method
您需要执行此特定语言才能在Application类中选择。
答案 1 :(得分:1)
尝试在您的活动中使用recreate()。这种方法在我的案例中是成功的。如果你在Fragment上,那么使用getActivity()。recreate();
SharedPreferences.Editor editor = prefs.edit();
editor.putString(Constants.APP_STATE.SAVED_LOCALE, localeString);
editor.apply();
getActivity().recreate();
覆盖您的活动的以下方法:
@Override
protected void attachBaseContext(Context newBase) {
SharedPreferences prefs = newBase.getSharedPreferences(Constants.APP_STATE.STATE_SHARED_PREFERENCES, MODE_PRIVATE);
String localeString = prefs.getString(Constants.APP_STATE.SAVED_LOCALE, Constants.DEFAULTS.DEFAULT_LOCALE);
Locale myLocale = new Locale(localeString);
Locale.setDefault(myLocale);
Configuration config = newBase.getResources().getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
config.setLocale(myLocale);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N){
Context newContext = newBase.createConfigurationContext(config);
super.attachBaseContext(newContext);
return;
}
} else {
config.locale = myLocale;
}
super.attachBaseContext(newBase);
getResources().updateConfiguration(config, getResources().getDisplayMetrics());
当用户设置想要的语言环境时,您要做的是将其保存到SharedPreferences中的某个字符串中,并调用recreate()of activity。然后,这将调用attachBaseContext(Context context),在此方法中,将正确的语言环境设置为配置,然后将使用此配置创建新的上下文。之后,新的上下文将被发送到超级类,它将更新应用程序上下文并显示正确的语言环境。
这也很好,因为下次启动应用程序时会自动设置区域设置。
答案 2 :(得分:0)
更改区域设置是Configuration
,这会导致您的活动重启。还有许多其他因素具有相同的效果,例如orientation
,keyboardHidden
。照顾你的活动状态。
如果重新启动活动,则需要恢复大量的活动 数据,重新建立网络连接或执行其他密集型操作 操作,然后由于配置更改可能会完全重启 用户体验缓慢。此外,你可能无法做到 使用系统的Bundle完全恢复您的活动状态 使用onSaveInstanceState()回调为您保存 - 它不是 旨在携带大型对象(如位图)和其中的数据 它必须序列化然后反序列化,这可能会消耗很多 内存并使配置变化缓慢。在这种情况下, 您可以减轻重新初始化部分活动的负担 通过在a重新启动活动时保留片段 配置改变。此片段可以包含对有状态的引用 你想要保留的对象。
不是最好的做法,但你可以处理它
<activity android:name=".MyActivity"
android:configChanges="locale"
android:label="@string/app_name">
然后在你的活动中
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Do your stuff here
}
记得照顾好你的州。使用setRetainFragment(true)
是一种很好的方法。阅读this