Android 內多語言切換實現


前言:

網上有很多安卓內多語言切換的文章,我也看了一些,很多都千篇一律,而且還是有問題,我就自己重新改了一下。整好分享給各位同學,廢話不多說,我們正式開始

效果圖

QQ截圖20200823185850.png
QQ截圖20200823185900.png
QQ截圖20200823185920.png
我們在點擊切換語言的按鈕時候彈窗dialog 然后用戶可以選擇 簡體中文 英文 繁體中文 跟隨系統 四種選項 ,這是我們基本的需求

具體實現

首先我們要在資源文件res目錄下面創建多語言的目錄文件夾 values values-en values-zh-rTW values-TW 如圖所示:
QQ截圖20200823190245.png
我們適配多語言的只需要在 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的屬性配置)

如圖:

QQ截圖20200823192700.png
所以目前的解決方案就是用values-TW來替代:

 myLocale = new Locale("TW",Locale.TRADITIONAL_CHINESE.getCountry());

我這邊目前是這樣處理來兼容繁體中文切換不生效的做法 ,如果你有更好的方案 麻煩留言大家一起探討。

最后總結:

Android 內多語言的切換網上的文章也挺多的,基本都千篇一律 很多有紕漏 ,這邊也是翻了一下源碼勉強能夠兼容繁體中文,有興趣學的的同學可以私下多多交流 最后希望我的文章能幫助到各位解決問題 ,以后我還會貢獻更多有用的代碼分享給大家。各位同學如果覺得文章還不錯 ,麻煩給關注和star,小弟在這里謝過啦 也可以加我個人QQ/微信(1693891473)

項目地址:

碼雲 :https://gitee.com/qiuyu123/language_demo.git

QQ交流群:92437359.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM