9

这是一种难以描述的效果。

我们的 Android 应用支持两种语言,但我们不使用系统语言,而是让用户在设置中进行设置。然后,在附加应用程序的 BaseContext 之前,我们设置语言环境配置。

// in Application class
override fun attachBaseContext(base: Context) {
   super.attachBaseContext(LocaleHelper.onAttach(base))
}

// the LocaleHelper
fun onAttach(context: Context): Context {
   return setLocale(context, getPersistedLanguage(context), getPersistedCountry(context))
}

这样,attachBaseContext 调用会获得一个上下文,该上下文的语言环境设置为例如“de”而不是“en”——即使设备是英文的。

到目前为止,这很有效,并且根据设置,来自上下文的所有资源都使用该语言。然而,我们现在为夜间模式添加了另一个设置(即让用户可以选择将“主题”设置为“正常”或“暗模式”)。

出于这个原因,这个想法是设置这样的东西

if (enableDarkMode) {
  AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
} else {
  AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}

在 Application 的 onCreate() 中(我们也在 Activity 中尝试过)。

但是,这样做时,资源(至少有一些)突然加载了设备区域设置。菜单条目采用设备语言。但是,检查 Locale.getLanguage() 给了我配置的语言和动态调用的字符串(例如 context.getString(R.string.xyz))也以正确配置的语言显示。

这导致假设菜单资源在某种程度上(重新)加载(再次)但不尊重来自 JVM 的设置区域设置。

有谁知道如何找到那个错误?我们在这里缺少什么?菜单资源是否以不同方式加载?

4

2 回答 2

3

我刚刚发现了一个 hacky 解决方案,但如果有人遇到同样的问题,这可能会有所帮助:

我添加到清单中的活动

android:configChanges="uiMode"

告诉应用程序“自己处理 ui 模式更改”。在这种情况下,资源保持“不变”,但我不确定这种变化可能会产生什么其他影响。

因此,如果您对让系统/应用程序自行处理夜间模式更改时出了什么问题有任何进一步的提示,请告诉我。

于 2019-10-17T12:43:32.457 回答
0

也许迟到了,但这可以帮助其他人。

我设法确保黑暗主题不会改变语言环境。

为此,我有一个片段可以通过切换黑暗主题来启用。

设置片段:

switchPreference.setOnPreferenceChangeListener((preference, isSwitchOn) -> {
            if((boolean) isSwitchOn){
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            } else {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            }
            return true;
        });

然后在父活动中,我只需要覆盖 attachBaseContext !

设置活动:

@Override
    protected void attachBaseContext(Context newBase) {

        // Get configuration and resources before onCreate method
        Resources resources = newBase.getResources();
        Configuration configuration = new Configuration(resources.getConfiguration());
        configuration.uiMode = Configuration.UI_MODE_NIGHT_UNDEFINED;
        Context context = newBase.createConfigurationContext(configuration);

        // Set locale with configuration saved
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        String langue = sharedPreferences.getString("langage_pref", "fr");
        Locale locale = new Locale(langue);
        Locale.setDefault(locale);
        configuration.setLocale(locale);
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());

        super.attachBaseContext(newBase);
    }

希望对你有帮助!:D

于 2021-05-25T13:03:03.930 回答