欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 多语言切换

程序员文章站 2022-03-03 22:14:43
前言:Android应用的开发不可能仅仅针对某一个国家或者区域使用,因此APP必须支持多种语言,为了实现这个特性,Android给出了一个解决方案,在res文件夹下通过values+语言编码来实现多国语言的支持(中间採用连字符号-连接)比如:values-es代表英文,在网上看过不少关于多语言切换的文章,但都没有达到自己的效果。1、在项目res目录下新建需要的语言配置文件这里新建了3种语言文字,需要其他语种的自行添加语种简称中文(中国)values-zh-rCN中文...

前言:Android应用的开发不可能仅仅针对某一个国家或者区域使用,因此APP必须支持多种语言,为了实现这个特性,Android给出了一个解决方案,在res文件夹下通过values+语言编码来实现多国语言的支持(中间採用连字符号-连接)比如:values-es代表英文,在网上看过不少关于多语言切换的文章,但都没有达到自己的效果。

1、在项目res目录下新建需要的语言配置文件

Android 多语言切换
Android 多语言切换
Android 多语言切换
Android 多语言切换

这里新建了3种语言文字,需要其他语种的自行添加
语种 简称
中文(中国) values-zh-rCN
中文(中国*) values-zh-rTW
中文(中国香港) values-zh-rHK
英语(美国) values-en-rUS
英语(英国) values-en-rGB
英文(澳大利亚) values-en-rAU
英文(加拿大) values-en-rCA
英文(爱尔兰) values-en-rIE
英文(印度) values-en-rIN
英文(新西兰) values-zh-rHK
英文(新加坡) values-en-rNZ
英文(南非) values-en-rZA
阿拉伯文(埃及) values-ar-rEG
阿拉伯文(以色列) values-ar-rIL
保加利亚文 values-bg-rBG

等等

解决Android 7.0 App 内切换语言不生效的问题

Android 7.0及以前版本,Configuration 中的语言相当于是App的全局设置:

public static void changeAppLanguage(Context context, String newLanguage){
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();

    // app locale
    Locale locale = getLocaleByLanguage(newLanguage);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        configuration.setLocale(locale);
    } else {
        configuration.locale = locale;
    }

    // updateConfiguration
    DisplayMetrics dm = resources.getDisplayMetrics();
    resources.updateConfiguration(configuration, dm);
}

然后在继承application的类中调用即可:

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        onLanguageChange();
    }

    /**
     * Handling Configuration Changes
     * @param newConfig newConfig
     */
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        onLanguageChange();
    }

    private void onLanguageChange() {
        String language;//读取App配置
        AppLanguageUtils.changeAppLanguage(this, language);
    }
}

Android7.0及之后版本,使用了LocaleList,Configuration中的语言设置可能获取的不同,而是生效于各自的Context。

这会导致:Android7.0使用的方式,有些Activity可能会显示为手机的系统语言。

Android7.0 优化了对多语言的支持,废弃了updateConfiguration()方法,替代方法:createConfigurationContext(), 而返回的是Context。

也就是语言需要植入到Context中,每个Context都植入一遍。

我自己的使用方式如下:

1.创建工具类
public class AppLanguageUtils {

    public static HashMap<String, Locale> mAllLanguages = new HashMap<String, Locale>(8) {{
        put(Constants.ENGLISH, Locale.ENGLISH);
        put(Constants.CHINESE, Locale.SIMPLIFIED_CHINESE);
        put(Constants.SIMPLIFIED_CHINESE, Locale.SIMPLIFIED_CHINESE);
        put(Constants.TRADITIONAL_CHINESE, Locale.TRADITIONAL_CHINESE);
        put(Constants.FRANCE, Locale.FRANCE);
        put(Constants.GERMAN, Locale.GERMANY);
        put(Constants.HINDI, new Locale(Constants.HINDI, "IN"));
        put(Constants.ITALIAN, Locale.ITALY);
    }};

    @SuppressWarnings("deprecation")
    public static void changeAppLanguage(Context context, String newLanguage) {
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();

        // app locale
        Locale locale = getLocaleByLanguage(newLanguage);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            configuration.setLocale(locale);
        } else {
            configuration.locale = locale;
        }

        // updateConfiguration
        DisplayMetrics dm = resources.getDisplayMetrics();
        resources.updateConfiguration(configuration, dm);
    }


    private static boolean isSupportLanguage(String language) {
        return mAllLanguages.containsKey(language);
    }

    public static String getSupportLanguage(String language) {
        if (isSupportLanguage(language)) {
            return language;
        }

        if (null == language) {//为空则表示首次安装或未选择过语言,获取系统默认语言
            Locale locale = Locale.getDefault();
            for (String key : mAllLanguages.keySet()) {
                if (TextUtils.equals(mAllLanguages.get(key).getLanguage(), locale.getLanguage())) {
                    return locale.getLanguage();
                }
            }
        }
        return Constants.ENGLISH;
    }

    /**
     * 获取指定语言的locale信息,如果指定语言不存在{@link #mAllLanguages},返回本机语言,如果本机语言不是语言集合中的一种{@link #mAllLanguages},返回英语
     *
     * @param language language
     * @return
     */
    public static Locale getLocaleByLanguage(String language) {
        if (isSupportLanguage(language)) {
            return mAllLanguages.get(language);
        } else {
            Locale locale = Locale.getDefault();
            for (String key : mAllLanguages.keySet()) {
                if (TextUtils.equals(mAllLanguages.get(key).getLanguage(), locale.getLanguage())) {
                    return locale;
                }
            }
        }
        return Locale.ENGLISH;
    }


    public static Context attachBaseContext(Context context, String language) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, language);
        } else {
            return context;
        }
    }


    @TargetApi(Build.VERSION_CODES.N)
       private static Context updateResources(Context context, String language) {
        Resources resources = context.getResources();
        Locale locale = AppLanguageUtils.getLocaleByLanguage(language);

           Configuration configuration = resources.getConfiguration();
           configuration.setLocale(locale);
           configuration.setLocales(new LocaleList(locale));
           return context.createConfigurationContext(configuration);
       }

}
2.在继承application的类中重写attachBaseContext()方法等操作
private static Context sContext;
    private String language;

    @Override
    protected void attachBaseContext(Context base) {
super.attachBaseContext(AppLanguageUtils.attachBaseContext(base, getAppLanguage(base)));
    }

    @Override
    public void onCreate() {
        super.onCreate();
        sContext = this;
        spu = new SharedPreferencesUtil(getApplicationContext());
        language = spu.getString("language");
        onLanguageChange();
    }

    public static Context getContext() {
        return sContext;
    }

    /**
     * Handling Configuration Changes
     * @param newConfig newConfig
     */
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        onLanguageChange();
    }

    private void onLanguageChange() {
 //       AppLanguageUtils.changeAppLanguage(this, AppLanguageUtils.getSupportLanguage(getAppLanguage(this)));
        AppLanguageUtils.changeAppLanguage(this, AppLanguageUtils.getSupportLanguage(language));
    }

    private String getAppLanguage(Context context) {
        String appLang = PreferenceManager.getDefaultSharedPreferences(context)
                .getString("language", Constants.ENGLISH);
        return appLang ;
    }
3.在需要切换语言的SetLanguageActivity中设置切换方法
private void onChangeAppLanguage(String newLanguage) {
        spu.putString("language", newLanguage);
        AppLanguageUtils.changeAppLanguage(this, newLanguage);
        AppLanguageUtils.changeAppLanguage(App.getContext(), newLanguage);
        this.recreate();
    }
4.跳转到 SetLanguageActivity 的原界面语言需要刷新
//携参跳转
startActivityForResult(new Intent(OriginActivity.this, SetLanguageActivity.class), CHANGE_LANGUAGE_REQUEST_CODE);
//切换后返回刷新
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
         if (requestCode == CHANGE_LANGUAGE_REQUEST_CODE) {
            recreate();
        }
    }

参考:解决Android 7.0 App内切换语言不生效的问题

   Android多语言切换(兼容安卓9、10)

   若想实现:切完语言立即刷新然后还是停留当前页

本文地址:https://blog.csdn.net/weixin_42814000/article/details/108170307