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
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)的以后更改语言配置,我们需要重新替换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);
}
}