Android应用内切换语言
Android应用内切换语言
前言
Android中实现国际化相对来说还是简单的,因为Android有很独特的资源管理方式,我们可以很轻松的创建资源支持不同语言.
资源文件的的使用
android是在res/values目录下通过不同values文件夹的命名来匹配不同的资源
values-语言代码-r国家代码
例如:values-zh-rCN(中文)和values-en(英文)
先看效果:
一些帮助工具
国家_地区语言速查表:http://www.cnblogs.com/Mien/archive/2008/08/22/1273950.html
一键实现语言国际化插件
https://github.com/JantHsueh/AndroidLocalizationer
API 25 (Android 7.1.1) 以下的方案
Resources resources = getContext().getResources(); DisplayMetrics dm = resources.getDisplayMetrics(); Configuration config = resources.getConfiguration(); config.locale = Locale.getDefault() resources.updateConfiguration(config, dm);
通过以上代码我们就能通过更改Configuration配置来进行APP语言切换,但是
在API 25以后推荐我们使用,Context.createConfigurationContext(Configuration),Resources.updateConfiguration(config, dm)被弃用
开始兼容API 25 (Android 7.1.1)
API 25 (Android 7.1.1)的以后更改语言配置,我们需要重新替换Context,把Context替换成设置了指定语言的Context对象,我们可以采取以下方案。
1.重写一个ContextWrapper类 ContextWrapper构造函数中必须包含一个真正的Context引用,同时ContextWrapper中提供了attachBaseContext()用于给ContextWrapper对象中指定真正的Context对象,调用ContextWrapper的方法都会被转向其所包含的真正的Context对象。
2.每个Activity都替换一次Context,这里我们可以把封装在BaseActivity中。
@Override protected void attachBaseContext(Context newBase) { SharedPreferences preferences = newBase.getSharedPreferences(SupportLanguageUtil.LANGENGE, Context.MODE_PRIVATE); String selectedLanguage = preferences.getString(SupportLanguageUtil.LANGENGE, ""); super.attachBaseContext(SupportLanguageUtil.attachBaseContext(newBase, selectedLanguage)); }
项目中用到工具栏SupportLanguageUtil,只需要调用changeLanguage 静态方法
public class SupportLanguageUtil { public static final String LANGENGE = "language"; // 简体中文 public static final String SIMPLIFIED_CHINESE = "zh"; // 英文 public static final String ENGLISH = "en"; // 繁体中文 public static final String TRADITIONAL_CHINESE = "zh-hant"; // 法语 public static final String FRANCE = "fr"; // 德语 public static final String GERMAN = "de"; // 意大利语 public static final String ITALIAN = "it"; //日语 public static final String JAPAN = "ja"; private static Map<String, Locale> mSupportLanguages = new HashMap<String, Locale>(7) {{ put(ENGLISH, Locale.ENGLISH); put(SIMPLIFIED_CHINESE, Locale.SIMPLIFIED_CHINESE); put(TRADITIONAL_CHINESE, Locale.TRADITIONAL_CHINESE); put(FRANCE, Locale.FRANCE); put(GERMAN, Locale.GERMANY); put(ITALIAN, Locale.ITALY); put(JAPAN, Locale.JAPAN); }}; /** * 在需要切换语言的地方调用该方法, * @param context 所在 activity * @param lang 切换的语言 eg: SIMPLIFIED_CHINESE */ public static void changeLanguage(Context context,String lang){ SharedPreferences preferences = context.getSharedPreferences(SupportLanguageUtil.LANGENGE, Context.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putString(LANGENGE, lang); editor.commit(); reLoadMainActivity(context); } /** *重新加载MainActivity * @param activity */ private static void reLoadMainActivity(Context activity){ Intent intent = new Intent(activity, MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); activity.startActivity(intent); // 杀掉进程 android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); } /** * 是否支持此语言 * * @param language language * @return true:支持 false:不支持 */ public static boolean isSupportLanguage(String language) { return mSupportLanguages.containsKey(language); } /** * 获取支持语言 * * @param language language * @return 支持返回支持语言,不支持返回系统首选语言 */ @TargetApi(Build.VERSION_CODES.N) public static Locale getSupportLanguage(String language) { if (isSupportLanguage(language)) { return mSupportLanguages.get(language); } return getSystemPreferredLanguage(); } /** * 获取系统首选语言 * * @return Locale */ @RequiresApi(api = Build.VERSION_CODES.N) public static Locale getSystemPreferredLanguage() { Locale locale; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { locale = LocaleList.getDefault().get(0); } else { locale = Locale.getDefault(); } return locale; } private static void applyLanguage(Context context, String newLanguage) { Resources resources = context.getResources(); Configuration configuration = resources.getConfiguration(); Locale locale = SupportLanguageUtil.getSupportLanguage(newLanguage); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // apply locale configuration.setLocale(locale); } else { // updateConfiguration configuration.locale = locale; DisplayMetrics dm = resources.getDisplayMetrics(); resources.updateConfiguration(configuration, dm); } } /** * 切换应用内语言调用该方法 * @param context * @param language * @return */ public static Context attachBaseContext(Context context, String language) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { return createConfigurationResources(context, language); } else { applyLanguage(context, language); return context; } } @TargetApi(Build.VERSION_CODES.N) private static Context createConfigurationResources(Context context, String language) { Resources resources = context.getResources(); Configuration configuration = resources.getConfiguration(); Locale locale; if (TextUtils.isEmpty(language)) {//如果没有指定语言使用系统首选语言 locale = SupportLanguageUtil.getSystemPreferredLanguage(); } else {//指定了语言使用指定语言,没有则使用首选语言 locale = SupportLanguageUtil.getSupportLanguage(language); } configuration.setLocale(locale); return context.createConfigurationContext(configuration); }}
更多相关文章
- Android 链式调用(方法链)
- Android Activity之间切换出现短暂黑屏的处理方法
- Android开机启动Activity或者Service方法
- 【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介
- android语音识别方法示例代码
- Android下java方法和JS方法的互调
- Android 中LayoutInflater(布局加载器)源码篇之parseInclude方法