AppCompat DayNight 主题总是显示为 Light 主题?

AppCompat DayNight theme always appears as a Light theme?

我正在使用 version 23.2 中引入的 AppCompat 的新 Theme.AppCompat.DayNight 主题,但它不会自动在白天(浅色)和夜晚(深色)主题之间切换,而是始终显示为浅色主题。我怎样才能让它切换到深色主题?

that same 23.2 blog post

中所述

By default, whether it is ‘night’ will match the system value (from UiModeManager.getNightMode())

然而,截至目前,这实际上意味着它等同于 MODE_NIGHT_NO,因为唯一触发夜间模式的是姜饼时代的汽车码头。

这意味着在当前设备上,在使用 DayNight 主题时看到深色主题的唯一方法是使用 NIGHT_MODE_YES 或 NIGHT_MODE_AUTO

如官方post和Chris Banes' post on DayNight所述,您可以在全局级别或本地级别更改模式。

全局级别依赖于静态 AppCompatDelegate.setDefaultNightMode() 方法,该方法在整个应用程序中设置 DayNight 模式。由于这仅在您的进程处于活动状态时适用(即,它只是内存中的标志),因此您需要确保每次启动应用程序时都设置它。 Chris post 推荐的一种方法是将其设置在自定义应用程序 class:

的静态方法中
static {
    AppCompatDelegate.setDefaultNightMode(
        AppCompatDelegate.MODE_NIGHT_...);
}
public class MyApplication extends Application {

如果您只想更改单个 activity/dialog 的模式,则可以改为调用 getDelegate().setLocalNightMode():

public class MyActivity extends AppCompatActivity {
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState == null) {
      // Set the local night mode to some value
      getDelegate().setLocalNightMode(
                AppCompatDelegate.MODE_NIGHT_...);
      // Now recreate for it to take effect
      recreate();
    }
  }
}

这只会改变单个实例 - 您会注意到对 recreate() 的调用 - 已经膨胀的视图不会受到夜间模式变化的影响,因此您可以强制 activity 重新创建自身以获得更新值。

当然,克里斯 post 也说

Also remember that the default is MODE_NIGHT_FOLLOW_SYSTEM, so if we add a user-visible setting to the platform in the future, AppCompat will automatically use it.

Android Lollipop with AppCompat 23.2.0 中似乎存在错误:Google Issue Tracker

以下代码仅适用于 Lollipop 之前的版本:

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