天天看點

app内切換語言

最近項目要做到中英文切換的功能,調查了很久現在講解及記錄一下

首先android 支援多語言的操作,先要在你的res的values中建立一套你的語言系統的strings.xml

右鍵點選res 

app内切換語言

選中android resource file 并選擇locale 

app内切換語言

這時點選右面的那個箭頭

app内切換語言

這時可以選擇你要的那個語言

以上是我們的準備工作,下面直接代碼

public class LocaleUtils {
     //中文
    public static final Locale LOCALE_CHINESE = Locale.CHINESE;
    /**
     * 英文
     */
    public static final Locale LOCALE_ENGLISH = Locale.ENGLISH;
    /**
     * 儲存SharedPreferences的檔案名
     */
    private static final String LOCALE_FILE = "LOCALE_FILE";
    /**
     * 儲存Locale的key
     */
    private static final String LOCALE_KEY = "LOCALE_KEY";

    /**
     * 擷取使用者設定的Locale
     *
     * @param pContext Context
     * @return Locale
     */
    public static Locale getUserLocale(Context pContext) {
        SharedPreferences _SpLocale = pContext.getSharedPreferences(LOCALE_FILE, Context.MODE_PRIVATE);
        String _LocaleJson = _SpLocale.getString(LOCALE_KEY, "");
        return jsonToLocale(_LocaleJson);
    }

    /**
     * 擷取目前的Locale
     *
     * @param pContext Context
     * @return Locale
     */
    public static Locale getCurrentLocale(Context pContext) {
        Locale _Locale;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //7.0有多語言設定擷取頂部的語言
            _Locale = pContext.getResources().getConfiguration().getLocales().get(0);
        } else {
            _Locale = pContext.getResources().getConfiguration().locale;
        }
        return _Locale;
    }

    /**
     * 儲存使用者設定的Locale
     *
     * @param pContext    Context
     * @param pUserLocale Locale
     */
    public static void saveUserLocale(Context pContext, Locale pUserLocale) {
        SharedPreferences _SpLocal = pContext.getSharedPreferences(LOCALE_FILE, Context.MODE_PRIVATE);
        SharedPreferences.Editor _Edit = _SpLocal.edit();
        String _LocaleJson = localeToJson(pUserLocale);
        _Edit.putString(LOCALE_KEY, _LocaleJson);
        _Edit.apply();
    }

    /**
     * Locale轉成json
     *
     * @param pUserLocale UserLocale
     * @return json String
     */
    private static String localeToJson(Locale pUserLocale) {
        Gson _Gson = new Gson();
        return _Gson.toJson(pUserLocale);
    }

    /**
     * json轉成Locale
     *
     * @param pLocaleJson LocaleJson
     * @return Locale
     */
    private static Locale jsonToLocale(String pLocaleJson) {
        Gson _Gson = new Gson();
        return _Gson.fromJson(pLocaleJson, Locale.class);
    }

    /**
     * 更新Locale
     *
     * @param pContext       Context
     * @param pNewUserLocale New User Locale
     */
    public static void updateLocale(Context pContext, Locale pNewUserLocale) {
        if (needUpdateLocale(pContext, pNewUserLocale)) {
            Configuration _Configuration = pContext.getResources().getConfiguration();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                _Configuration.setLocale(pNewUserLocale);
            } else {
                _Configuration.locale = pNewUserLocale;
            }
            DisplayMetrics _DisplayMetrics = pContext.getResources().getDisplayMetrics();
            pContext.getResources().updateConfiguration(_Configuration, _DisplayMetrics);
            saveUserLocale(pContext, pNewUserLocale);
        }
    }

    /**
     * 判斷需不需要更新
     *
     * @param pContext       Context
     * @param pNewUserLocale New User Locale
     * @return true / false
     */
    public static boolean needUpdateLocale(Context pContext, Locale pNewUserLocale) {
        return pNewUserLocale != null && !getCurrentLocale(pContext).equals(pNewUserLocale);
    }

}
           

自己封裝的語言設定的類

在使用時要在application  中設定語言

Locale userLocale=LocaleUtils.getUserLocale(this);
if(userLocale == null){
    userLocale = LocaleUtils.LOCALE_CHINESE;
}
LocaleUtils.updateLocale(this, userLocale);
           

而且為了不響應系統設定的語言的影響我們還要

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    Locale _UserLocale=LocaleUtils.getUserLocale(this);
    //系統語言改變了應用保持之前設定的語言
    if (_UserLocale != null) {
        Locale.setDefault(_UserLocale);
        Configuration _Configuration = new Configuration(newConfig);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            _Configuration.setLocale(_UserLocale);
        } else {
            _Configuration.locale =_UserLocale;
        }
        getResources().updateConfiguration(_Configuration, getResources().getDisplayMetrics());
    }
}
           

在切換時

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    if (LocaleUtils.getUserLocale(mContext).equals(LocaleUtils.LOCALE_CHINESE)) {
        LocaleUtils.saveUserLocale(mContext, LocaleUtils.LOCALE_ENGLISH);
    } else if (LocaleUtils.getUserLocale(mContext).equals(LocaleUtils.LOCALE_ENGLISH)) {
        LocaleUtils.saveUserLocale(mContext, LocaleUtils.LOCALE_CHINESE);
    }
} else {
    if (LocaleUtils.getUserLocale(mContext).equals(LocaleUtils.LOCALE_CHINESE)) {
        LocaleUtils.updateLocale(mContext, LocaleUtils.LOCALE_ENGLISH);
    } else if (LocaleUtils.getUserLocale(mContext).equals(LocaleUtils.LOCALE_ENGLISH)) {
        LocaleUtils.updateLocale(mContext, LocaleUtils.LOCALE_CHINESE);
    }
}      
restartAct();
           
/**
 * 重新開機目前Activity
 */
private void restartAct() {
    if (Build.VERSION.SDK_INT >= 11) {
        recreate();
    } else {
        finish();
        Intent _Intent = new Intent(this, LoginActivity.class);
        startActivity(_Intent);
        //清除Activity退出和進入的動畫
        overridePendingTransition(0, 0);
    }
}
           

注意這時在8.0手機上是有問題的,還需要在(activity或者BaseActivity中添加)

@Override
protected void attachBaseContext(Context newBase) {
    Context context = languageWork(newBase);
    super.attachBaseContext(context);

}

private Context languageWork(Context context) {
    // 8.0及以上使用createConfigurationContext設定configuration
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        return updateResources(context);
    } else {
        return context;
    }
}

@RequiresApi(api = Build.VERSION_CODES.O)
private Context updateResources(Context context) {
    Resources resources = context.getResources();
    Locale locale = LocaleUtils.getUserLocale(context);;
    if (locale==null) {
        return context;
    }
    Configuration configuration = resources.getConfiguration();
    configuration.setLocale(locale);
    configuration.setLocales(new LocaleList(locale));
    return context.createConfigurationContext(configuration);
}
           

以上就是切換的整個過程