1. 程式人生 > >優雅的實現app國際化功能

優雅的實現app國際化功能

       最近在做國際化功能,這裡講過程中的技術點記錄一下。

        

       第一。如果切換不同語言之後讀取不同的values語言內容

       1.所有的activity中(一般都是baseactivit中),重寫下面的方法

/**
     * 設定修改語言
     *
     * @param newBase
     */
    @Override
    protected void attachBaseContext(Context newBase) {
        Context context = MyContextWrapper.wrap(newBase);
        super.attachBaseContext(context);
    }

      2.重寫contextwarpper類

public class MyContextWrapper extends android.content.ContextWrapper {

    public MyContextWrapper(Context base) {
        super(base);
    }

    public static ContextWrapper wrap(Context context) {
        Locale newLocale;
        switch (context.getSharedPreferences(MainActivity.SP_NAME, MODE_PRIVATE).getInt(MainActivity.LANGUAGE, -1)) {
            case -1://沒有做過設定,讀取手機語言
                String locale = Locale.getDefault().getLanguage();
                if (TextUtils.isEmpty(locale)) {
                    context.getSharedPreferences(MainActivity.SP_NAME, MODE_PRIVATE).edit().putInt(MainActivity.LANGUAGE, 1).commit();
                    newLocale = Locale.CHINESE;
                    MainActivity.sLanguage = 1;
                } else if (locale.contains("en")) {
                    context.getSharedPreferences(MainActivity.SP_NAME, MODE_PRIVATE).edit().putInt(MainActivity.LANGUAGE, 2).commit();
                    newLocale = Locale.ENGLISH;
                    MainActivity.sLanguage = 2;
                } else {
                    context.getSharedPreferences(MainActivity.SP_NAME, MODE_PRIVATE).edit().putInt(MainActivity.LANGUAGE, 1).commit();
                    newLocale = Locale.CHINESE;
                    MainActivity.sLanguage = 1;
                }
                break;
            case 2://設定為英語
                newLocale = Locale.ENGLISH;
                MainActivity.sLanguage = 2;
                break;
            default://預設為漢語
                newLocale = Locale.CHINESE;
                MainActivity.sLanguage = 1;
                break;
        }
        Resources res = context.getResources();
        Configuration configuration = res.getConfiguration();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            configuration.setLocale(newLocale);
            LocaleList localeList = new LocaleList(newLocale);
            LocaleList.setDefault(localeList);
            configuration.setLocales(localeList);
            context = context.createConfigurationContext(configuration);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            configuration.setLocale(newLocale);
            context = context.createConfigurationContext(configuration);
        }
        return new ContextWrapper(context);
    }
}

    第二.經過上面的步驟已經可以實現切換語言之後讀取不同的values下面的內容值了。但是呢,由於現在都是app內部實現語言切換,所以如果僅僅實現上面的步驟,那麼僅僅實現了系統語言切換app也跟著切換語言。下面就是實現app內部實現語言切換的過程。

    1.app內部切換語言通常都是會進入一個單獨的頁面,然後切換語言。當切換語言頁面關閉的時候呢,我們需要將任務棧中的所有頁面都清空。這個過程如下:

Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        overridePendingTransition(R.anim.change_language_enter, R.anim.change_language_exit);

    這樣就可以實現了。上面加入了頁面關閉的切換動畫,為了是切換更加順暢。但是會有如下問題。

    2.上面的操作如果mainactivity有大量的任務需要做,比如巢狀很多的fragment等等,那麼就會出現明顯的閃屏現象,非常不友好,為此需要給mainactivity的主題增加如下屬性:

<item name="android:windowDisablePreview">true</item>

    至此,一個優雅的切換國際化語言的方案結束了。

demo下載地址 :https://download.csdn.net/download/zhq217217/10448158