前言:Android应用的开发不可能仅仅针对某一个国家或者区域使用,因此APP必须支持多种语言,为了实现这个特性,Android给出了一个解决方案,在res文件夹下通过values+语言编码来实现多国语言的支持(中间採用连字符号-连接)比如:values-es代表英文,在网上看过不少关于多语言切换的文章,但都没有达到自己的效果。
解决问题:
1、可同时在应用进入选择和内部切换
2、解决高版本切换语言不生效问题
3、解决切换闪屏、白屏问题
4、重启应用语言设置数据持久化
效果:
1、在项目res目录下新建需要的语言配置文件
这里新建了3种语言文字,需要其他语种的自行添加
语种 | 简称 |
---|---|
中文(中国) | values-zh-rCN |
中文(台湾) | values-zh-rTW |
中文(香港) | values-zh-rHK |
英语(美国) | values-en-rUS |
英语(英国) | values-en-rGB |
英文(澳大利亚) | values-en-rAU |
英文(加拿大) | values-en-rCA |
英文(爱尔兰) | values-en-rIE |
英文(印度) | values-en-rIN |
英文(新西兰) | values-zh-rHK |
英文(新加坡) | values-en-rNZ |
英文(南非) | values-en-rZA |
阿拉伯文(埃及) | values-ar-rEG |
阿拉伯文(以色列) | values-ar-rIL |
保加利亚文 | values-bg-rBG |
加泰罗尼亚文 | values-ca-rES |
捷克文 | values-cs-rCZ |
丹麦文 | values-da-rDK |
德文(奥地利) | values-de-rAT |
德文(瑞士) | values-de-rCH |
德文(德国) | values-de-rDE |
德文(列支敦士登): | values-de-rLI |
希腊文 | values-el-rGR |
西班牙文(西班牙) | values-es-rES |
西班牙文(美国) | values-es-rUS |
芬兰文(芬兰) | values-fi-rFI |
法文(比利时) | values-fr-rBE |
法文(加拿大) | values-fr-rCA |
法文(瑞士) | values-fr-rCH |
法文(法国) | values-fr-rFR |
希伯来文) | values-iw-rIL |
印地文 | values-hi-rIN |
克罗里亚文 | values-hr-rHR |
匈牙利文 | values-hu-rHU |
印度尼西亚文 | values-in-rID |
意大利文(瑞士) | values-it-rCH |
意大利文(意大利) | values-it-rIT |
日文 | values-ja-rJP |
韩文 | values-ko-rKR |
立陶宛文 | valueslt-rLT |
拉脱维亚文 | values-lv-rLV |
挪威博克马尔文 | values-nb-rNO |
荷兰文(比利时) | values-nl-BE |
荷兰文(荷兰) | values-nl-rNL |
波兰文 | values-pl-rPL |
葡萄牙文(巴西) | values-pt-rBR |
葡萄牙文(葡萄牙) | values-pt-rPT |
罗马尼亚文 | values-ro-rRO |
俄文 | values-ru-rRU |
斯洛伐克文 | values-sk-rSK |
斯洛文尼亚文 | values-sl-rSI |
塞尔维亚文 | values-sr-rRS |
瑞典文 | values-sv-rSE |
泰文 | values-zh-rHK |
塔加洛文 | values-th-rTH |
土耳其文 | values–r-rTR |
乌克兰文 | values-uk-rUA |
越南文 | values-vi-rVN |
2、测试文字:
中文简体:
<string name="home1_title">首页</string>
<string name="home2_title">信息</string>
<string name="home3_title">系统</string>
<string name="home4_title">我的</string>
<string name="test_hint">安卓是一种基于Linux内核(不包含GNU组件)的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。Android操作系统最初由Andy Rubin开发,主要支持手机。2005年8月由Google收购注资。2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。随后Google以Apache开源许可证的授权方式,发布了Android的源代码。</string>
中文繁体(4个标题换了因为简繁一致看不出效果):
<string name="home1_title">首頁</string>
<string name="home2_title">細膩</string>
<string name="home3_title">曉曦</string>
<string name="home4_title">訂單</string>
<string name="test_hint">安卓是一種基於Linux內核(不包含GNU元件)的自由及開放原始程式碼的作業系統。主要使用於移動設備,如智慧手機和平板電腦,由Google公司和開放手機聯盟領導及開發。Android作業系統最初由Andy Rubin開發,主要支援手機。2005年8月由Google收購注資。2007年11月,Google與84家硬體製造商、軟體發展商及電信營運商組建開放手機聯盟共同研發改良Android系統。隨後Google以Apache開源許可證的授權方式,發佈了Android的原始程式碼。</string>
英文:
<string name="home1_title">Home page</string>
<string name="home2_title">information</string>
<string name="home3_title">system</string>
<string name="home4_title">my</string>
<string name="test_hint">Android is a free and open source operating system based on the Linux kernel (which does not include GNU components). Primarily used on mobile devices such as smartphones and tablets, it is led and developed by Google and the open handset alliance. The Android operating system was originally developed by Andy Rubin and mainly supports mobile phones. It was acquired by Google in August 2005. In November 2007, Google formed an open handset alliance with 84 hardware manufacturers, software developers and telecom operators to develop and improve Android. Then Google released the source code for Android under the Apache open source license.</string>
3、LanguageUtil语言切换工具类:
public class LanguageUtil {
private static final String ENGLISH = "en";
private static final String CHINESE = "ch";
private static final String TRADITIONAL_CHINESE = "zh_rTW";
private static HashMap<String, Locale> languagesList = new HashMap<String, Locale>(3) {{
put(ENGLISH, Locale.ENGLISH);
put(CHINESE, Locale.CHINESE);
put(TRADITIONAL_CHINESE, Locale.TRADITIONAL_CHINESE);
}};
public static void changeAppLanguage(Activity activity, String language, Class<?> cls) {
Resources resources = activity.getResources();
Configuration configuration = resources.getConfiguration();
// app locale 默认简体中文
Locale locale = getLocaleByLanguage(StringUtils.isEmpty(language) ? "zh" : language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLocale(locale);
} else {
configuration.locale = locale;
}
DisplayMetrics dm = resources.getDisplayMetrics();
resources.updateConfiguration(configuration, dm);
LogUtils.e("设置的语言:" + language);
//finish();
// 重启app
Intent intent = new Intent(activity, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
activity.startActivity(intent);
//加载动画
//activity.overridePendingTransition(R.anim.anim_right_in, R.anim.anim_left_out);
//activity.overridePendingTransition(0, 0);
}
private static Locale getLocaleByLanguage(String language) {
if (isContainsKeyLanguage(language)) {
return languagesList.get(language);
} else {
Locale locale = Locale.getDefault();
for (String key : languagesList.keySet()) {
if (TextUtils.equals(languagesList.get(key).getLanguage(), locale.getLanguage())) {
return locale;
}
}
}
return Locale.ENGLISH;
}
private static boolean isContainsKeyLanguage(String language) {
return languagesList.containsKey(language);
}
}
4、使用方法(自行添加3个按钮):
@OnClick({R.id.language1, R.id.language2, R.id.language3})
public void onClick(View view) {
switch (view.getId()) {
case R.id.language1:
//中文简体
showSaveLanguage("zh");
break;
case R.id.language2:
//中文繁体
showSaveLanguage("zh_rTW");
break;
case R.id.language3:
//英文
showSaveLanguage("en");
break;
}
}
private void showSaveLanguage(String language){
//设置的语言、重启的类一般为应用主入口(微信也是到首页)
LanguageUtil.changeAppLanguage(this, language, MainActivity.class);
//保存设置的语言
SpUserUtils.putString(this, "language", language);
}
5、SpUserUtils .class存储类
public class SpUserUtils {
private static SharedPreferences sp;
private static SharedPreferences getSp(Context context) {
if (sp == null) {
sp = context.getSharedPreferences("SpUtil", Context.MODE_PRIVATE);
}
return sp;
}
public static void putString(Context context, String key, String value) {
SharedPreferences preferences = getSp(context);
//存入数据
SharedPreferences.Editor editor = preferences.edit();
editor.putString(key, value);
editor.commit();
}
public static String getString(Context context, String key) {
SharedPreferences preferences = getSp(context);
return preferences.getString(key, "");
}
public static void clearString(Context context, String key) {
SharedPreferences sp = getSp(context);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
editor.apply();
// editor.clear();
// editor.commit();
}
}
6、解决应用重启后数据持久化问题:
public class WelcomeActivity extends AppCompatActivity {
//防止重复打开界面
private static boolean ISFIRST = true;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
String language = SpUserUtils.getString(this, "language");
if (ISFIRST) {
ISFIRST = false;
LanguageUtil.changeAppLanguage(this, language, WelcomeActivity.class);
}
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
7、优化白屏问题:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<!--禁用窗口的预览动画-->
<item name="android:windowDisablePreview">true</item>
</style>