【问题标题】:Changing application language (localization) wont apply on api 23 android更改应用程序语言(本地化)不适用于 api 23 android
【发布时间】:2019-05-13 23:21:46
【问题描述】:

我在 android 应用程序中遇到了一些本地化问题。

当我在 api 级别 24 及以上测试时更改语言的功能正常工作,但是当我在模拟器 api 级别 23 上更改语言时,它只是不会应用本地变化。我在很多论坛上都读到过这个,我已经尝试了几乎所有提供的解决方案,但它就是行不通。

重要的是,关闭弹出菜单的动画,即 listPreference,比 Android Nougat 上的关闭动画有点奇怪,所以它已经闻起来有些不规则。

重要提示是我在我的 api 级别 23 或 Marshmallow 的物理设备上运行应用程序,但问题仍然存在。

在下面的部分中,我提供了一些对这种情况很重要的代码,另一方面,我省略了一些文件,如 strings.xmlpreferences.xml对于这种情况,这不是必需的。所以这里的主要焦点是能够改变应用程序语言。如果你们有任何线索,我会请他与我们分享可能是什么问题。


设置语言环境的助手类

package com.metropolitan.hangouter;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Configuration;
import android.os.Build;

import java.util.Locale;

public class MyContextWrapper extends ContextWrapper {

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

@SuppressWarnings("deprecation")
public static ContextWrapper wrap(Context context, String language) {
    Configuration config = context.getResources().getConfiguration();
    Locale sysLocale = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        sysLocale = getSystemLocale(config);
    } else {
        sysLocale = getSystemLocaleLegacy(config);
    }
    if (!language.equals("") && !sysLocale.getLanguage().equals(language)) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            setSystemLocale(config, locale);
        } else {
            setSystemLocaleLegacy(config, locale);
        }

    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        context = context.createConfigurationContext(config);
    } else {
        context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
    }
    return new MyContextWrapper(context);
}


@SuppressWarnings("deprecation")
public static Locale getSystemLocaleLegacy(Configuration config) {
    return config.locale;
}

@TargetApi(Build.VERSION_CODES.N)
public static Locale getSystemLocale(Configuration config) {
    return config.getLocales().get(0);
}

@SuppressWarnings("deprecation")
public static void setSystemLocaleLegacy(Configuration config, Locale locale) {
    config.locale = locale;
}

@TargetApi(Build.VERSION_CODES.N)
public static void setSystemLocale(Configuration config, Locale locale) {
    config.setLocale(locale);
}
}

然后在我的主要活动以及其他方法中,我称之为对我们至关重要的一种。

override fun attachBaseContext(newBase: Context) {
    preferences = PreferenceManager.getDefaultSharedPreferences(newBase)
    vred = preferences.getString("languageKey", "no selection")!!
    val locale = Locale(vred)
    super.attachBaseContext(MyContextWrapper.wrap(newBase, locale.language))
}

此方法也在具有相同功能的 SettingsActivity 中调用,它将本地配置附加到 baseContext,当然,由于所做的更改,我需要刷新活动,并且我正在处理该事件。

所以这个方法是在正确的地方和正确的时间调用的。换句话说,我每次 onPreferenceChange 都会刷新活动。我的应用程序是用 kotlin 编写的,但是这个 MyContextWrapper 类是在 java 中。现在就是这样,如果有人需要更多信息,我将很乐意提供。

【问题讨论】:

    标签: android kotlin localization locale android-6.0-marshmallow


    【解决方案1】:

    这可能是因为以下原因:

    从 Android 7.0(API 级别 24)开始,Android 提供了增强的 支持多语言用户,允许他们选择多个 设置中的语言环境。 Android 极大地提供了这种能力 扩大支持的语言环境数量并改变 系统解析资源。

    你可以阅读更多关于这个here

    如果您的资源名为 xx_XX,请尝试删除 XX,这在旧版本上对我有用。否则指定完全限定的语言环境。

    【讨论】:

    • 我尝试将 strings.xml 资源重命名为没有国家标签的东西,这是大写的缩写,它也适用于模拟器以及物理设备。唯一的缺点是重命名过程必须通过项目视图层次结构手动完成。无论如何,感谢您的建议,因为现在它终于可以工作了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    相关资源
    最近更新 更多