AppCompat DayNight 主题不适用于 Android 6.0?

AppCompat DayNight theme not work on Android 6.0?

我正在使用 Android Support Library 23.2

中添加的新 Theme.AppCompat.DayNight

在 Android 5.1 上运行良好。

在 Android 6.0 上,activity 看起来像使用浅色主题,但对话框看起来使用深色主题。

我的申请class:

public class MyApplication extends Application {
    static {
        AppCompatDelegate.setDefaultNightMode(
                AppCompatDelegate.MODE_NIGHT_YES);
    }
}

我的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"/>

我显示对话框的代码:

new AlertDialog.Builder(mContext, R.style.Dialog_Alert)
                .setTitle("Title")
                .setMessage("Message")
                .show();

setDefaultNightMode之后添加getDelegate().applyDayNight();

Google 已修复它以支持 23.2.1

旧答案:

在Android 6.0 上,系统的夜间模式设置默认为UiModeManager.MODE_NIGHT_NO,在调用onCreate 之前它将更改为Resources.Configuration.uiMode。但是,支持库在 AppCompatActivity 中应用 onCreate 中的夜间模式设置,为时已晚,我认为这就是它在 6.0 上不起作用的原因。

因此,如果我们可以在 AppCompatActivity 中覆盖 getResources() 并更改 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_);
    }
}

注意:如果您的应用没有位置权限,您的应用将不会有与系统相同的计算结果。这意味着支持库可能认为现在是晚上,而系统没有,这将导致您的 UI 看起来有些暗有些亮。

最好的方法是等待 Google 修复它。

只需将其添加到您的 values-v21

<style name="Theme.AppCompat.DayNight">

为我工作 完成。

此问题已在 https://code.google.com/p/android/issues/detail?id=201910

上报告

但在发布 Android 支持库后,修订版 23.2.1(2016 年 3 月)。 此问题已解决。

修复了夜间模式和 API 级别 23

的兼容性问题

将支持库更新为 Android Support Library to 23.2.1

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

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;
}

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

@Override
protected void attachBaseContext(Context base) {
    Context context = ThemePicker.getInstance().setupTheme(base);
    super.attachBaseContext(context);
}

截至目前,不需要 Gradle 依赖项来启用 夜间模式 除了 androidx.appcompat:appcompat:1.0.2 已经存在。确保在 styles.xml 文件中将默认主题从 Theme.AppCompat.Light.DarkActionBar 更改为 Theme.AppCompat.DayNight.DarkActionBar,然后执行 AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) 切换到夜间模式。我已经在 APIv23(Android 6.0) 及更高版本中对其进行了测试,并且工作正常。 如需更好的解释,请参阅 this codelab by Android