跳转至

Android语言热切换方案

方案

结合之前做过的两次不重启App进行语言切换给出当前最优的解决方案。

主要思路是在SharedPreference中存储当前的语言环境,一旦切换语言,则跳回主界面(主界面的launchModesingleTask),在onCreate中先设置语言环境再渲染页面,在onResume判断是否刷新语言,若刷新语言则调用recreate()方法重新渲染对应语言环境的界面。

  1. BaseActivity基类
/**
 * Created by ykh on 2017/9/8.
 * 基类
 */

public class BaseActivity extends AppCompatActivity {
    protected Activity context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;
    }

    /**
     * load the language user selected
     * 0 CHINESE 1 ENGLISH other SYSTEM
     */
    public void setLanguage() {
        if(Utils.hasValue(context,"Language")){
            int current_language  = Utils.getIntValue(context,"Language");
            if(current_language == 0){
                setLang(Locale.SIMPLIFIED_CHINESE);
            }else if(current_language == 1) {
                setLang(Locale.ENGLISH);
            }else{
                setLang(Locale.getDefault());
            }
        }
    }

    /**
     * set language locale
     * @param locale locale
     */
    private void setLang(Locale locale) {
        // 获得res资源对象
        Resources resources = getResources();
        // 获得设置对象
        Configuration config = resources.getConfiguration();
        // 获得屏幕参数:主要是分辨率,像素等。
        DisplayMetrics dm = resources.getDisplayMetrics();
        // 语言
        config.locale = locale;
        resources.updateConfiguration(config, dm);
    }
}

所有界面的类均继承BaseActivity,觉得麻烦可以直接将BaseActivity中的setLanguagesetLang方法拷贝至Util中调用。

  1. AndroidManifest.xml中设置MainActivitylaunchModesingleTask
 <activity android:name=".ui.MainActivity"
        android:screenOrientation="portrait"
        android:launchMode="singleTask">
        ...
  1. MainActivity继承BaseActivity,并设置onCreate时,在界面加载前设置语言环境
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 在界面加载(setContentView方法调用前)前设置语言环境
    setLanguage();
    setContentView(R.layout.activity_main);
}
  1. LanguageActivity中切换语言,SharedPreferenceLanguage存0时为中文,Language存1时为英文
@OnClick(R.id.setting_ll_language_chinese)
void language_chinese() {
    Utils.putIntValue(context, "Language", 0);
    Utils.putBooleanValue(context, "reset_language", true);
    startActivity(new Intent(LanguageActivity.this, MainActivity.class));
}

@OnClick(R.id.setting_ll_language_english)
void language_english() {
    Utils.putIntValue(context, "Language", 1);
    Utils.putBooleanValue(context, "reset_language", true);
    startActivity(new Intent(LanguageActivity.this, MainActivity.class));
}
  1. MainActivity onResume中根据SharedPreference判断是否切换语言以及切换至什么语言。
@Override
protected void onResume() {
    super.onResume();
    if (Utils.getBooleanValue(context, "reset_language")) {
        Utils.putBooleanValue(context, "reset_language", false);
        //重新渲染界面
        recreate();
    }
}

recreate();方法会重新渲染本界面,会重新调用MainActivityonCreate方法,由于设置语言环境在前,渲染界面在后,那么MainActivity的界面就将立即变为设置的语言环境对应的界面。

至此热更新Android App语言环境介绍完成

ISO 639-1 对照表

Language / Locale                 Supported since version

English, US (en_US)               1.1
German, Germany (de_DE)           1.1
Chinese, PRC (zh_CN)              1.5
Chinese, Taiwan (zh_TW)           1.5
Czech, Czech Republic (cs_CZ)     1.5
Dutch, Belgium (nl_BE)            1.5
Dutch, Netherlands (nl_NL)        1.5
English, Australia (en_AU)        1.5
English, Britain (en_GB)          1.5
English, Canada (en_CA)           1.5
English, New Zealand (en_NZ)      1.5
English, Singapore(en_SG)         1.5
French, Belgium (fr_BE)           1.5
French, Canada (fr_CA)            1.5
French, France (fr_FR)            1.5
French, Switzerland (fr_CH)       1.5
German, Austria (de_AT)           1.5
German, Liechtenstein (de_LI)     1.5
German, Switzerland (de_CH)       1.5
Italian, Italy (it_IT)            1.5
Italian, Switzerland (it_CH)      1.5
Japanese (ja_JP)                  1.5
Korean (ko_KR)                    1.5
Polish (pl_PL)                    1.5
Russian (ru_RU)                   1.5
Spanish (es_ES)                   1.5
Arabic, Egypt (ar_EG)             2.3
Arabic, Israel (ar_IL)            2.3
Bulgarian, Bulgaria (bg_BG)       2.3
Catalan, Spain (ca_ES)            2.3
Croatian, Croatia (hr_HR)         2.3
Danish, Denmark(da_DK)            2.3
English, India (en_IN)            2.3
English, Ireland (en_IE)          2.3
English, Zimbabwe (en_ZA)         2.3
Finnish, Finland (fi_FI)          2.3
Greek, Greece (el_GR)             2.3
Hebrew, Israel (iw_IL)*           2.3
Hindi, India (hi_IN)              2.3
Hungarian, Hungary (hu_HU)        2.3
Indonesian, Indonesia (in_ID)*    2.3
Latvian, Latvia (lv_LV)           2.3
Lithuanian, Lithuania (lt_LT)     2.3
Norwegian-Bokmål, Norway(nb_NO)   2.3
Portuguese, Brazil (pt_BR)        2.3
Portuguese, Portugal (pt_PT)      2.3
Romanian, Romania (ro_RO)         2.3
Serbian (sr_RS)                   2.3
Slovak, Slovakia (sk_SK)          2.3
Slovenian, Slovenia (sl_SI)       2.3
Spanish, US (es_US)               2.3
Swedish, Sweden (sv_SE)           2.3
Tagalog, Philippines (tl_PH)      2.3
Thai, Thailand (th_TH)            2.3
Turkish, Turkey (tr_TR)           2.3
Ukrainian, Ukraine (uk_UA)        2.3
Vietnamese, Vietnam (vi_VN)       2.3

English为例,codeen_US,语言文件夹名称应为values-en,获取Locale方法如下:

Locale english = new Locale("en", "US");