Android 多語(yǔ)言切換無(wú)需重啟APP的方式

簡(jiǎn)述

當(dāng)APP需要給提供多種語(yǔ)音供用戶使用的時(shí)候,作為開(kāi)發(fā)者的我們自然要涉及到多語(yǔ)言切換的開(kāi)發(fā),希望我提供的方式能給需要的小伙伴們一點(diǎn)思路,老規(guī)矩先上圖。

效果如下,可能看起來(lái)會(huì)比較卡(不知道為啥黑屏?xí)r間卡了好久,實(shí)際效果是一閃而過(guò))


效果圖.gif

實(shí)現(xiàn)方式

這是最常運(yùn)用的最普遍的方式,通過(guò)創(chuàng)建不同的value 語(yǔ)言文件夾下的的string.xml ,當(dāng)更改時(shí),切換使用對(duì)應(yīng)的字符資源。
讓我們先來(lái)創(chuàng)建對(duì)應(yīng)的字符資源文件夾。在main目錄下的res文件夾右鍵新建一個(gè)資源文件夾


操作截圖1.png

選中Locale,導(dǎo)入限定資源里


操作截圖2.png

此時(shí)會(huì)出現(xiàn)各種語(yǔ)言資源,在此項(xiàng)目中,我將新增中文(zh)與英文(en)字符資源 (懶得找的小伙伴其實(shí)只要知道對(duì)應(yīng)的語(yǔ)言文化代碼,直接自己創(chuàng)建命名也可)


操作截圖3.png

建完之后的目錄:


操作截圖4.png

接著再導(dǎo)入本次要使用的EventBus,用于廣播通知(也可用Broadcast,這次主要是對(duì)于語(yǔ)言切換的實(shí)現(xiàn),故不展開(kāi)講)

implementation 'org.greenrobot:eventbus:3.0.0'

然后我們先來(lái)實(shí)現(xiàn)一個(gè)抽象基類:BaseActivity,讓其它Activity繼承其特性,寫(xiě)一些共有方法,便于我們維護(hù)何使用,這里是為了實(shí)現(xiàn)多語(yǔ)言切換時(shí),不用在每個(gè)Activity中實(shí)現(xiàn)切換語(yǔ)言通知時(shí),界面重建與減少繁瑣的編寫(xiě)EventBus 的訂閱與注銷

public abstract class BaseActivity extends AppCompatActivity {
    public final static String SWITCH_LANGUAGE = "Language";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setLanguage();
        EventBus.getDefault().register(this);
        setContentView(getViewResId());
        init();
    }

    protected void init() {

    }

    protected abstract int getViewResId();



    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(String msg) {
        switch (msg){
            case SWITCH_LANGUAGE:
                setLanguage();
                recreate();//刷新界面
                break;
        }

    }

    private void setLanguage() {
        Locale myLocale = new Locale(SPUtils.getLanguage(this));
        Resources res = getResources();
        DisplayMetrics dm = res.getDisplayMetrics();
        Configuration conf = res.getConfiguration();
        conf.locale = myLocale;
        res.updateConfiguration(conf, dm);
    }


}

setLanguage()方法中設(shè)置了我們的地理語(yǔ)言環(huán)境,將我們?cè)O(shè)置Locale賦值給Configuration,設(shè)置為我們需要的語(yǔ)言環(huán)境,再調(diào)用 recreate()方法銷毀界面再重新創(chuàng)建,此方法只有在API>26以上版本才存在。調(diào)用后新創(chuàng)建的活動(dòng)的生命周期:onCreate->onStart->onResume
其中SPUtils 工具類是用來(lái)在關(guān)閉應(yīng)用后,重新打開(kāi)我們的APP時(shí),記錄用戶設(shè)置的切換語(yǔ)言類型(它本質(zhì)就是一個(gè)小型數(shù)據(jù)庫(kù),隨著應(yīng)用卸載而被銷毀)

public class SPUtils {
    public static void setLanguage(Context context, String language) {
        SharedPreferences.Editor editor = context.getSharedPreferences("Language", context.MODE_PRIVATE).edit();
        editor.putString("language", language);
        editor.commit();
    }

    public static String getLanguage(Context context) {
        SharedPreferences editor = context.getSharedPreferences("Language", context.MODE_PRIVATE);
        return editor.getString("language","zh");//默認(rèn)中文
    }
}

回到我們的主界面來(lái),在XML上直接使用我們?cè)趕trings中定義的內(nèi)容,復(fù)制strings到對(duì)values-en 與 values-zh,自行修改中文與英文的的內(nèi)容


目錄文件.png
zh\string.png
en\string.png

在XML上的使用是通過(guò)@string/name 方式設(shè)置

操作截圖5.png

在代碼中則是通過(guò)調(diào)用Resources 的getString 方法獲取對(duì)應(yīng)資源文件的id來(lái)設(shè)置

getResources().getString(R.string.to_one)

現(xiàn)在我們通過(guò)跳轉(zhuǎn)ActivityOne(記得要繼承我們編寫(xiě)的基類)界面,點(diǎn)擊按鈕切換語(yǔ)言,XML布局就不給出了

public class ActivityOne extends BaseActivity {

    @Override
    protected void init() {
        onClickEvent();
    }

    @Override
    protected int getViewResId() {
        return R.layout.activity_one;
    }

    private void onClickEvent() {
        findViewById(R.id.tv_chinese).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                SPUtils.setLanguage(ActivityOne.this, "zh");
                EventBus.getDefault().post(BaseActivity.SWITCH_LANGUAGE);
            }
        });

        findViewById(R.id.tv_english).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SPUtils.setLanguage(ActivityOne.this, "en");
                EventBus.getDefault().post(BaseActivity.SWITCH_LANGUAGE);
            }
        });
    }
}

至此,就實(shí)現(xiàn)了語(yǔ)言切換的功能,錄制圖已貼在最頂部,當(dāng)然切換方法還有其它方式,這里給出較為常用的一種,希望能給需要的小伙伴們一點(diǎn)啟發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容