3 回答
![?](http://img1.sycdn.imooc.com/533e4c0500010c7602000200-100-100.jpg)
TA贡献1825条经验 获得超4个赞
好。最后,我设法找到了解决方案。
首先,您应该知道在25个API Resources.updateConfiguration(...)中已弃用。因此,您可以执行以下操作:
1)您需要创建自己的ContextWrapper,它将覆盖baseContext中的所有配置参数。例如,这是我的ContextWrapper,可以正确更改Locale。注意context.createConfigurationContext(configuration)方法。
public class ContextWrapper extends android.content.ContextWrapper {
public ContextWrapper(Context base) {
super(base);
}
public static ContextWrapper wrap(Context context, Locale newLocale) {
Resources res = context.getResources();
Configuration configuration = res.getConfiguration();
if (BuildUtils.isAtLeast24Api()) {
configuration.setLocale(newLocale);
LocaleList localeList = new LocaleList(newLocale);
LocaleList.setDefault(localeList);
configuration.setLocales(localeList);
context = context.createConfigurationContext(configuration);
} else if (BuildUtils.isAtLeast17Api()) {
configuration.setLocale(newLocale);
context = context.createConfigurationContext(configuration);
} else {
configuration.locale = newLocale;
res.updateConfiguration(configuration, res.getDisplayMetrics());
}
return new ContextWrapper(context);
}
}
2)这是您在BaseActivity中应该做的事情:
@Override
protected void attachBaseContext(Context newBase) {
Locale newLocale;
// .. create or get your new Locale object here.
Context context = ContextWrapper.wrap(newBase, newLocale);
super.attachBaseContext(context);
}
注意:
如果要在某个地方更改应用程序的区域设置,请记住要重新创建活动。您可以使用此解决方案覆盖所需的任何配置。
![?](http://img1.sycdn.imooc.com/533e4c5600017c5b02010200-100-100.jpg)
TA贡献1812条经验 获得超5个赞
受各种代码的启发(例如:我们的Stackoverflow团队(大声疾呼)),我制作了一个简单得多的版本。该ContextWrapper扩展名是不必要的。
首先,假设您有2个按钮用于2种语言,即EN和KH。在按钮的onClick中,将语言代码保存到中SharedPreferences,然后调用activity recreate()方法。
例:
@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.btn_lang_en:
//save "en" to SharedPref here
break;
case R.id.btn_lang_kh:
//save "kh" to SharedPref here
break;
default:
break;
}
getActivity().recreate();
}
然后创建一个ContextWrapper可能在Utils类中返回的静态方法(这就是我所做的,lul)。
public static ContextWrapper changeLang(Context context, String lang_code){
Locale sysLocale;
Resources rs = context.getResources();
Configuration config = rs.getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
sysLocale = config.getLocales().get(0);
} else {
sysLocale = config.locale;
}
if (!lang_code.equals("") && !sysLocale.getLanguage().equals(lang_code)) {
Locale locale = new Locale(lang_code);
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
config.setLocale(locale);
} else {
config.locale = locale;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
context = context.createConfigurationContext(config);
} else {
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
}
}
return new ContextWrapper(context);
}
最后,从加载的语言代码SharedPreferences中的所有活动'S attachBaseContext(Context newBase)方法。
@Override
protected void attachBaseContext(Context newBase) {
String lang_code = "en"; //load it from SharedPref
Context context = Utils.changeLang(newBase, lang_code);
super.attachBaseContext(context);
}
奖励:为了节省键盘上的汗水,我创建了一个LangSupportBaseActivity类,扩展了类Activity并在其中使用最后一块代码。并且我将所有其他活动扩展LangSupportBaseActivity。
例:
public class LangSupportBaseActivity extends Activity{
...blab blab blab so on and so forth lines of neccessary code
@Override
protected void attachBaseContext(Context newBase) {
String lang_code = "en"; //load it from SharedPref
Context context = Utils.changeLang(newBase, lang_code);
super.attachBaseContext(context);
}
}
public class HomeActivity extends LangSupportBaseActivity{
...blab blab blab
}
![?](http://img1.sycdn.imooc.com/54585094000184e602200220-100-100.jpg)
TA贡献1854条经验 获得超8个赞
从Android 7.0+开始,我的应用程序的某些部分不再更改其语言。即使使用上面提出的新方法。应用程序和活动上下文的更新对我有所帮助。这是Activity子类覆盖的Kotlin示例:
private fun setApplicationLanguage(newLanguage: String) {
val activityRes = resources
val activityConf = activityRes.configuration
val newLocale = Locale(newLanguage)
activityConf.setLocale(newLocale)
activityRes.updateConfiguration(activityConf, activityRes.displayMetrics)
val applicationRes = applicationContext.resources
val applicationConf = applicationRes.configuration
applicationConf.setLocale(newLocale)
applicationRes.updateConfiguration(applicationConf,
applicationRes.displayMetrics)
}
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase)
setApplicationLanguage("fa");
}
注意:不建议使用updateConfiguration,但是无论如何,每个Activity的createConfigurationContext都保留一些字符串不变。
添加回答
举报