Android 多语言切换

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

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里新建了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)

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

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 如果要在代码中切换 Android 设备的语言并重启应用程序,可以使用以下代码: ``` // 获取系统配置对象 Configuration config = getResources().getConfiguration(); // 设置新的语言 config.locale = new Locale("en"); // 更新配置 getResources().updateConfiguration(config, getResources().getDisplayMetrics()); // 重启应用程序 Intent intent = new Intent(this, MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(intent); finish(); ``` 注意,需要自己实现MainActivity.class,更改"en"为需要切换语言 ### 回答2: Android切换语言重启的代码可以通过修改系统配置并重新启动Activity来实现。具体步骤如下: 1. 首先,需要创建一个共享参数(SharedPreferences)来保存所选的语言设置。在Activity中定义一个SharedPreferences对象,用于存储和读取语言设置。例如: ``` SharedPreferences preferences = getSharedPreferences("LanguagePrefs", MODE_PRIVATE); ``` 2. 在需要切换语言的地方,首先获取到用户所选择的新语言。假设语言选择是通过点击按钮来实现的,使用一个String变量`newLanguage`保存新语言的值。例如: ``` String newLanguage = "en"; // 假设新使用英文(en)作为语言 ``` 3. 在切换语言之前,将新语言的值保存到共享参数中,以便在重启Activity后继续使用。使用SharedPreferences编辑器(Editor)添加或修改语言设置。例如: ``` SharedPreferences.Editor editor = preferences.edit(); editor.putString("language", newLanguage); editor.apply(); ``` 4. 重新启动Activity。通过调用当前Activity的`recreate()`方法,强制重启当前Activity,以便应用切换到新的语言。例如: ``` recreate(); ``` 5. 在Activity的`onCreate()`方法中,读取保存的语言设置并应用到应用程序的配置中。通过读取共享参数中保存的语言设置,然后调用`ContextWrapper`类的`attachBaseContext()`方法传入新的配置。例如: ``` @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 读取共享参数中保存的语言设置 String language = preferences.getString("language", ""); // 根据新语言设置重新配置应用 Context context = ChangeLanguageActivity.this; LocaleUtils.setLocale(context, language); // 自定义工具类设置应用语言 // ... } ``` 6. 最后,重新定义一个自定义工具类`LocaleUtils`,用于应用程序级别的语言设置。例如: ``` public class LocaleUtils { public static void setLocale(Context context, String language) { Locale locale = new Locale(language); Locale.setDefault(locale); Resources resources = context.getResources(); Configuration configuration = resources.getConfiguration(); configuration.setLocale(locale); configuration.setLayoutDirection(locale); resources.updateConfiguration(configuration, resources.getDisplayMetrics()); } } ``` 通过以上步骤,当用户切换语言后,会重新启动当前Activity并应用新语言的配置。请注意,重启Activity可能会造成界面闪烁,所以可以添加一些过渡动画来提升用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值