前言:
網上有很多安卓內多語言切換的文章,我也看了一些,很多都千篇一律,而且還是有問題,我就自己重新改了一下。整好分享給各位同學,廢話不多說,我們正式開始
效果圖
我們在點擊切換語言的按鈕時候彈窗dialog 然后用戶可以選擇 簡體中文 英文 繁體中文 跟隨系統 四種選項 ,這是我們基本的需求
具體實現
首先我們要在資源文件res目錄下面創建多語言的目錄文件夾 values values-en values-zh-rTW values-TW 如圖所示:
我們適配多語言的只需要在 values values-en values-zh-rTW 這個三個目錄下面的string.xml文件里面寫入對應的引用的文本即可
簡體中文資源文件配置
<resources>
<string name="app_name">Language Demo</string>
<string name="lan_chinese">中文</string>
<string name="lan_en">英文</string>
<string name="text_content">這是內容顯示區</string>
<string name="select_language">選擇一個語言</string>
<string name="lan_zh_rTYW">繁體中文</string>
<string name="Follow_the_system">跟隨系統</string>
</resources>
英文資源文件配置
<resources>
<string name="app_name">Language Demo</string>
<string name="lan_chinese">Chinese</string>
<string name="lan_en">English</string>
<string name="text_content">Hello World!</string>
<string name="select_language">Choose a language</string>
<string name="lan_zh_rTYW">Chinese Traditional</string>
<string name="Follow_the_system">Follow the system</string>
</resources>
繁體中文資源文件配置
<resources>
<resources>
<string name="app_name">Language Demo</string>
<string name="lan_chinese">簡體中文</string>
<string name="lan_en">英文</string>
<string name="lan_zh_rTYW">繁體中文</string>
<string name="text_content">這是內容顯示區域</string>
<string name="select_language">選擇一種語言</string>
<string name="Follow_the_system">跟隨系統</string>
</resources>
</resources>
我們只需要這樣配置就然后在布局的xml文件里面引用可以達到適配多語言的效果 :
具體引用:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_content"
android:id="@+id/textView" />
<Button
android:id="@+id/btn_setting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="setting" />
</LinearLayout>
切換的dialog實現這個我用原生的AlertDialog 你們自己可以自定義繼承系統的Dialog來實現
final String[] cities = {getString(R.string.lan_chinese), getString(R.string.lan_en),getString(R.string.lan_zh_rTYW),getString(R.string.Follow_the_system)};
final String[] locals = {"zh_CN", "en","zh_TW","111"};
Button button = (Button)findViewById(R.id.btn_setting);
button.setText("Language");
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(SettingActivity.this);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle(R.string.select_language);
builder.setItems(cities, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String language=null;
if(which==3){
language= LanguageUtils.getCurrentLanguage();
Log.e(TAG, "onClick: language --- >"+language );
}else{
language=locals[which];
}
Store.setLanguageLocal(SettingActivity.this, language);
Intent intent = new Intent(Config.ACTION);
intent.putExtra("msg", "EVENT_REFRESH_LANGUAGE");
sendBroadcast(intent);
}
});
builder.show();
}
});
更新 Configuration 中的 locale 屬性
public void changeAppLanguage() {
String sta = Store.getLanguageLocal(this);
if(sta != null && !"".equals(sta)){
// 本地語言設置
Locale myLocale=null;
if(sta.equals("zh_CN")){
myLocale = new Locale(sta,Locale.CHINESE.getCountry());
}else if(sta.equals("zh_TW")){
myLocale = new Locale("TW",Locale.TRADITIONAL_CHINESE.getCountry());
}else if(sta.equals("en")||sta.equals("en_US")){
myLocale = new Locale( "en",Locale.ENGLISH.getCountry());
}
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
}
}
這里的語言種類獲取到的sta是重SharedPreferences 緩存里面獲取到的因為需要
SharedPreferences 工具類:
package com.language_demo;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class Store {
public static void setLanguageLocal(Context context, String language){
SharedPreferences preferences;
SharedPreferences.Editor editor;
preferences = PreferenceManager.getDefaultSharedPreferences(context);
editor = preferences.edit();
editor.putString("language", language);
editor.commit();
}
public static String getLanguageLocal(Context context){
SharedPreferences preferences;
preferences = PreferenceManager.getDefaultSharedPreferences(context);
String language = preferences.getString("language", "");
return language;
}
}
我們在dialog點擊事件里發送一個廣播通知 用來觸發刷新
Store.setLanguageLocal(SettingActivity.this, language);
Intent intent = new Intent(Config.ACTION);
intent.putExtra("msg", "EVENT_REFRESH_LANGUAGE");
sendBroadcast(intent);
然我們在baseActivity里面接收廣播重啟activity 來刷新多語言切換
BroadcastReceiver myBroadcastReceive = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("廣播", "----接收到的是----" + intent.getStringExtra("msg"));
if(intent.getStringExtra("msg").equals("EVENT_REFRESH_LANGUAGE")){
changeAppLanguage();
recreate();//刷新界面
}
}
};
關於Locale
實現多語言切換用到了Locale。Locale里很多常見國家和地區以及語言,如果我們做常見的語言,可以直接調用系統的,比如Locale.CHINESE。但是這次做的繁體中文的適配,略我坑一下。
繁體中文我們直接在Locale 屬性里面傳入 zh-rTW 但是切換沒有生效 我翻了下源碼只有TW的屬性配置我就要修改了
問題是,我最開始直接這樣寫的:
Locale myLocale = new Locale(sta);
到此我們說明下開頭提到到為什么多出了 values-TW目錄 是因為我發現在多語言切換更新 Configuration 中的 locale 屬性 的時候翻開源碼看到繁體中文(泛指港澳台並沒有看到zh-rTW的屬性配置)
如圖:
所以目前的解決方案就是用values-TW來替代:
myLocale = new Locale("TW",Locale.TRADITIONAL_CHINESE.getCountry());
我這邊目前是這樣處理來兼容繁體中文切換不生效的做法 ,如果你有更好的方案 麻煩留言大家一起探討。
最后總結:
Android 內多語言的切換網上的文章也挺多的,基本都千篇一律 很多有紕漏 ,這邊也是翻了一下源碼勉強能夠兼容繁體中文,有興趣學的的同學可以私下多多交流 最后希望我的文章能幫助到各位解決問題 ,以后我還會貢獻更多有用的代碼分享給大家。各位同學如果覺得文章還不錯 ,麻煩給關注和star,小弟在這里謝過啦 也可以加我個人QQ/微信(1693891473)
項目地址:
碼雲 :https://gitee.com/qiuyu123/language_demo.git