最近做公司的项目时,提出一个需求,需要根据APP内设置的语言显示对应的字符串。
开始以为挺简单的,首先在values文件下配置对应文件的翻译
然后新建一个类LanguageUtils,在切换语言的时候调用就行了,主要方法如下
public static void changeLanguage(int language,boolean isSave) { Resources mResources = BaseApplication.getInstance().getResources(); Configuration config = new Configuration(mResources.getConfiguration()); // 获得设置对象 switch (language) { case CacheConstant.SIMPLIFIED_CHINESE: config.locale = Locale.SIMPLIFIED_CHINESE;// 中文 Locale.setDefault(Locale.SIMPLIFIED_CHINESE); // config.setTo(config); if(isSave) { SPUtils.put(CacheConstant.LANGUAGE, CacheConstant.SIMPLIFIED_CHINESE); } break; case CacheConstant.ENGLISH: config.locale = Locale.ENGLISH; // 英文 Locale.setDefault(Locale.ENGLISH); // config.setTo(config); if(isSave) { SPUtils.put(CacheConstant.LANGUAGE, CacheConstant.ENGLISH); } break; case CacheConstant.TRADITIONAL_CHINESE: config.locale = Locale.TRADITIONAL_CHINESE; Locale.setDefault(Locale.TRADITIONAL_CHINESE); // config.setTo(config); if(isSave) { SPUtils.put(CacheConstant.LANGUAGE, CacheConstant.TRADITIONAL_CHINESE); } break; } mResources.updateConfiguration(config, null); }
同时新建个方法获取特定语言的字符串:
public static String getLocaleStringResource(Local requestedLocale,int resourceId, Context context) { String result; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { // use latest api Resources mResources = BaseApplication.getInstance().getResources(); Configuration config = mResources.getConfiguration(); config.setLocale(requestedLocale); result = context.createConfigurationContext(config).getText(resourceId).toString(); } else { // support older android versions Resources resources = context.getResources(); Configuration conf = resources.getConfiguration(); Locale savedLocale = conf.locale; resources.updateConfiguration(conf, null); config.setLocale(requestedLocale); // retrieve resources from desired locale result = resources.getString(resourceId); // restore original locale conf.locale = savedLocale; resources.updateConfiguration(conf, null); } return result; }
结果出现了一个问题,在activiy的横竖屏发生变化的时候,所有的字符串回还原成当前手机设置的语言
排查后发现在Application的onConfigChanged方法:
@CallSuper public void onConfigurationChanged(Configuration newConfig) { Object[] callbacks = collectComponentCallbacks(); if (callbacks != null) { for (int i=0; i<callbacks.length; i++) { ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig); } } }
Activity的onConfigChanged方法:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); getDelegate().onConfigurationChanged(newConfig); if (mResources != null) { // The real (and thus managed) resources object was already updated // by ResourcesManager, so pull the current metrics from there. final DisplayMetrics newMetrics = super.getResources().getDisplayMetrics(); mResources.updateConfiguration(newConfig, newMetrics); } }
可以看出在横竖屏切换的时候,调用了
mResources.updateConfiguration(newConfig, newMetrics);
这个方法,重新又设置了一次configuration。
所以解决办法就是override在Application的onConfigurationChanged方法:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); LanguageUtils.changeLanguage((int) SPUtils.get(CacheConstant.LANGUAGE, CacheConstant.SIMPLIFIED_CHINESE), false); }这样就可以了。