Android 多语言切换的一些bug与解决
2017-09-05 本文已影响189人
zhaoyubetter
参考:
- http://www.lai18.com/content/6602031.html
- https://jaeger.itscoder.com/android/2016/05/14/switch-language-on-android-app.html
- http://gunhansancar.com/change-language-programmatically-in-android/
具体设置可参考:
https://jaeger.itscoder.com/android/2016/05/14/switch-language-on-android-app.html
具体bug的产生,可参考:
http://www.lai18.com/content/6602031.html
解决方案
如果代码中,没有基类,或者,不喜欢使用基类,可使用 activity生命周期callback来解决:
工具类代码:
public final class LocaleUtils {
private static final String FILE_NAME = "better_language_info";
private static final String KEY_LANGUAGE = "key_language";
private static final String KEY_COUNTRY = "key_country";
/**
* 获取手机系统的Locale
*
* @return
*/
public static Locale getSystemLocale() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return LocaleList.getDefault().get(0);
}
return Locale.getDefault();
}
/**
* 设置 App 的Locale
*
* @param context
* @param loc
* @return
*/
public static void setAppLocale(Context context, Locale loc) {
if (loc != null) {
setUserSetLocale(context, loc);
Resources rs = context.getResources();
Configuration config = rs.getConfiguration();
DisplayMetrics dm = rs.getDisplayMetrics();
if (Build.VERSION.SDK_INT >= 17) {
config.setLocale(loc);
} else {
config.locale = loc;
}
context.getResources().updateConfiguration(config, dm);
}
}
/**
* 在activity 的 onResume or onConfigChange中调用此方法
* http://www.jianshu.com/p/47bbd34d2af8
*
* @param context
* @param loc
*/
public static void setLocaleWhenConfigChange(Context context, Locale loc) {
if (loc != null) {
Resources rs = context.getResources();
Configuration config = rs.getConfiguration();
DisplayMetrics dm = rs.getDisplayMetrics();
if (Build.VERSION.SDK_INT >= 17) {
config.setLocale(loc);
} else {
config.locale = loc;
}
context.getResources().updateConfiguration(config, dm);
}
}
/**
* 获取App Locale
*
* @param context
* @return
*/
public static Locale getAppLocale(Context context) {
Configuration config = context.getResources().getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
return config.getLocales().get(0);
else
return config.locale;
}
/**
* 获取用户设置的Locale
*
* @param context
* @return
*/
public static Locale getUserSetLocale(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
String lang = sp.getString(KEY_LANGUAGE, "");
String country = sp.getString(KEY_COUNTRY, "");
if (!TextUtils.isEmpty(lang) && !TextUtils.isEmpty(country)) {
return new Locale(lang, country);
}
return null;
}
/**
* 返回 en_US 格式
*
* @param context
* @return
*/
public static String getUserSetLocaleStr(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
String lang = sp.getString(KEY_LANGUAGE, "");
String country = sp.getString(KEY_COUNTRY, "");
if (!TextUtils.isEmpty(lang) && !TextUtils.isEmpty(country)) {
return String.format("%s_%s", lang, country);
}
return "";
}
/**
* 清空设置,跟随系统
*
* @param context
*/
public static void removeLocaleSet(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
final SharedPreferences.Editor edit = sp.edit();
edit.putString(KEY_LANGUAGE, "");
edit.putString(KEY_COUNTRY, "");
edit.apply();
}
/**
* 用户设置的Locale
*/
private static void setUserSetLocale(Context context, Locale locale) {
if (locale != null) {
try {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
final SharedPreferences.Editor edit = sp.edit();
edit.putString(KEY_LANGUAGE, locale.getLanguage());
edit.putString(KEY_COUNTRY, locale.getCountry());
edit.apply();
} catch (Exception e) {
}
}
}
}
- app 启动设置在 application 调用如下方法:
private static void setLocale(Context context) {
final Locale userSet = LocaleUtils.getUserSetLocale(context);
if (userSet != null && LocaleUtils.getAppLocale(context) != userSet) {
LocaleUtils.setAppLocale(context, userSet);
}
}
- 在 application类中,监听activity生命周期回调如下:
private void registerLifeActivityCallbacks() {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityResumed(Activity activity) {
// 切换语言,修复bug
final Locale userSetLocale = LocaleUtils.getUserSetLocale(activity);
LocaleUtils.setLocaleWhenConfigChange(activity, userSetLocale);
}
这种bugs 也是头痛,难道 google允许某一个页面,是中文,另一个页面是英文这种么?