前言
最近做了一款软件需要用到国际化(语言切换),同事负责这个模块,但是有bug,华为和小米手
机切换英文后,过一段时间部分模块会自动变回中文,他问我有没有遇到这个问题,我研究了一下
最后发现了问题原因。
正文:
切换语言的方法:
1、首先要在AndroidManifest.xml中的所有Activity加上标志位,尤其在Android4.2之后不仅要加上
locale标志还要加上layoutdirection标志位。只有这样,重启MainActivity的时候,
AcitivityManagerService不会把MainActivity作为重启,也就是不会重新执行它的生命周期,而是直
接调用了onConfigurationChanged的方法。
2、语言按钮的点击
switch (view.getId()) {
case R.id.rl_back:
finish();
break;
case R.id.rl_jianti:
if(!spUtils.getJianTi()){
initLanguage(Locale.SIMPLIFIED_CHINESE);
goToNewActivity();
spUtils.saveJianTi(true);
spUtils.saveFanTi(false);
spUtils.saveEnglish(false);
tv_jianti.setSelected(true);
tv_fanti.setSelected(false);
tv_english.setSelected(false);
}
break;
case R.id.rl_fanti:
if(!spUtils.getFanTi()){
initLanguage(Locale.TRADITIONAL_CHINESE);
goToNewActivity();
spUtils.saveJianTi(false);
spUtils.saveFanTi(true);
spUtils.saveEnglish(false);
tv_jianti.setSelected(false);
tv_fanti.setSelected(true);
tv_english.setSelected(false);
}
break;
case R.id.rl_english:
if (!spUtils.getEnglish()){
initLanguage(Locale.ENGLISH);
goToNewActivity();
spUtils.saveJianTi(false);
spUtils.saveFanTi(false);
spUtils.saveEnglish(true);
tv_jianti.setSelected(false);
tv_fanti.setSelected(false);
tv_english.setSelected(true);
}
break;
}
上面就是点击按钮切换不同的语言 ,先设置语言的配置,然后重新启动MainActivity,这里
没有重启App,只是清除了之前的任务栈,重新生成一个任务栈,启动MainActivity,同时对
设置的状态持久化(如果重启MainActivity的时候会有段时间的白屏的话,就不要重新生成任
务栈)。
public void initLanguage(Locale locale) {
Resources resources = getResources();
Configuration config = resources.getConfiguration();
DisplayMetrics dm = resources.getDisplayMetrics();
config.setLocale(locale);
resources.updateConfiguration(config, dm);
}
就是设置Configuration的语言参数来切换语言的。然后通过EventBus通知MainActivity重新启动
MessageEvent messageEvent = new MessageEvent();
messageEvent.setMessage(MessageEvent.FINISH_ACTIVITY);
EventBus.getDefault().post(messageEvent);
finish();
3、重启MainActivity
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
if (event.getMessage() == MessageEvent.LOGOIN_DL) {
goToShiJian();
initTongBu();
} else if (event.getMessage() == MessageEvent.FINISH_ACTIVITY) {
finish();
Intent intent = new Intent( mActivity, MainActivity.class );
//intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra( LOGIN_LANGUAGE, LOGIN_LANGUAGE );
startActivity( intent );
Log.i( "onMessageEvent: ", event.getMessage() + " - " );
}
}
切换成英文或者繁体的时候,切换fragment,会发现部分页面变回了简体中文。经过log打印,
发现这部分的fragment的的语言变回了中文。
Log.i(TAG, "###"+ AppUtils.getAppContext().getResources().getConfiguration().locale.getLanguage());
为了不再重新创建fragment,所有的fragment都不是通过replace加载的,而是通过hidde
和show进行切换的。对于华为手机、小米手机,在切换fragment的时候,fragment的
Configuration的语配置就会恢复默认的简体中文。所以对这两种手机的特性就要在
BaseFragment重新配置他的Configuration,这样不管fragment如何切换就不会有问题了。
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
Log.i(TAG, "###base "+ AppUtils.getAppContext().getResources().getConfiguration().locale.getLanguage());
initLanguageChange();
}
private void initLanguageChange() {
SpUtils spUtils = SpUtils.getInstance( mActivity );
if (spUtils.getJianTi()) {
initLanguage( Locale.SIMPLIFIED_CHINESE );
}
if (spUtils.getFanTi()) {
initLanguage( Locale.TRADITIONAL_CHINESE );
}
if (spUtils.getEnglish()) {
initLanguage( Locale.ENGLISH );
}
}
Android语言切换源码分析