AppCompat DayNight主题在Android 6.0上不起作用?

Rik*_*kka 11 xml android android-layout android-theme android-support-library

我正在使用新Theme.AppCompat.DayNight添加的Android Support Library 23.2

在Android 5.1上运行良好.

在Android 6.0上,活动看起来像使用灯光主题,但对话框看起来使用黑暗主题.

我的应用类:

public class MyApplication extends Application {
    static {
        AppCompatDelegate.setDefaultNightMode(
                AppCompatDelegate.MODE_NIGHT_YES);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的styles.xml

<style name="AppTheme" parent="Theme.AppCompat.DayNight">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

<style name="Dialog.Alert" parent="Theme.AppCompat.DayNight.Dialog.Alert"/>
Run Code Online (Sandbox Code Playgroud)

我的代码显示一个对话框:

new AlertDialog.Builder(mContext, R.style.Dialog_Alert)
                .setTitle("Title")
                .setMessage("Message")
                .show();
Run Code Online (Sandbox Code Playgroud)

Rik*_*kka 5

Google已在支持23.2.1中对其进行了修复

旧答案:

在Android 6.0上,系统的夜间模式设置默认值为UiModeManager.MODE_NIGHT_NO,它将Resources.Configuration.uiModeonCreate调用之前更改。然而,支持库中应用其夜间模式设置onCreateAppCompatActivity,一切都太迟了,我想这就是为什么它不能在6.0工作。

因此,如果我们可以覆盖getResources()AppCompatActivity和变化uiMode

旧答案:

这是修复无法在Android 6.0上运行的代码

public class Application extends android.app.Application {
    static {
        AppCompatDelegate.setDefaultNightMode(
                AppCompatDelegate.MODE_NIGHT_);
    }

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

        // add this code for 6.0
        // DO NOT DO THIS. It will trigger a system wide night mode.
        // This is the old answer. Just update appcompat.
        // UiModeManager uiManager = (UiModeManager) getSystemService(Context.UI_MODE_SERVICE);
        // uiManager.setNightMode(UiModeManager.MODE_NIGHT_);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:如果您的应用没有位置许可,则您的应用将不会具有相同的系统计算结果。这意味着支持库可能认为现在不是系统的夜晚,这将导致您的某些UI显得有些暗淡。

最好的方法是等待Google对其进行修复。

  • 不要这样 无需强制整个系统使用夜间模式,以便您可以在应用程序中使用它。等待23.2.1版的错误修正发布。(来源:我是支持库的首席工程师) (3认同)

Szy*_*ski 5

最好的解决方案是使用正确的配置更新上下文。这是我所做的一个片段:

public Context setupTheme(Context context) {

    Resources res = context.getResources();
    int mode = res.getConfiguration().uiMode;
    switch (getTheme(context)) {
        case DARK:
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            mode = Configuration.UI_MODE_NIGHT_YES;
            break;
        case LIGHT:
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            mode = Configuration.UI_MODE_NIGHT_NO;
            break;
        default:
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
            break;
    }

    Configuration config = new Configuration(res.getConfiguration());
    config.uiMode = mode;
    if (Build.VERSION.SDK_INT >= 17) {
        context = context.createConfigurationContext(config);
    } else {
        res.updateConfiguration(config, res.getDisplayMetrics());
    }
    return context;
}
Run Code Online (Sandbox Code Playgroud)

然后像这样在您的应用程序中使用上下文

@Override
protected void attachBaseContext(Context base) {
    Context context = ThemePicker.getInstance().setupTheme(base);
    super.attachBaseContext(context);
}
Run Code Online (Sandbox Code Playgroud)