I am using the new Theme.AppCompat.DayNight theme of AppCompat introduced in version 23.2, but instead of switching between a day (light) and night (dark) theme automatically, it always appears as a light theme. How can I get it to switch to a dark theme?
-
I believe this is the correct answer: http://stackoverflow.com/a/35701225/859190 – mariotaku Feb 29 '16 at 15:04
2 Answers
As specified in that same 23.2 blog post,
By default, whether it is ‘night’ will match the system value (from UiModeManager.getNightMode())
However, as of now, this effectively means that it is equivalent to MODE_NIGHT_NO
as the only thing that triggers night mode are car docks from the Gingerbread era.
This means that on current devices, the only way to see a dark theme when using a DayNight theme is to use NIGHT_MODE_YES or NIGHT_MODE_AUTO
As stated in both the official post and Chris Banes' post on DayNight, you can change the mode at either the global level or the local level.
The global level relies on the static AppCompatDelegate.setDefaultNightMode()
method, which sets the DayNight mode across your entire app. As this only applies while your process is alive (i.e., it is only an in memory flag), you need to make sure you set it every time your application is started. One recommended approach from Chris' post to do that is to set it in a static method of your custom Application class:
static {
AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_...);
}
public class MyApplication extends Application {
If, instead, you only want to change the mode for a single activity/dialog, you can instead call 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();
}
}
}
This changes just the single instance - you'll note the call to recreate()
- Views that have already been inflated won't be affected by a change in night mode, so you can force the activity to recreate itself to get the updated values.
Of course, Chris' post also states
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.

- 191,609
- 30
- 470
- 443
-
For changing other attributes when it is day or night, check out [this answer](http://stackoverflow.com/a/35629740/1676363) which explains how to use the `night` and `notnight` resource folders. – ianhanniballake Feb 26 '16 at 00:12
-
what about Pie? It is possible to change the theme at the Display settings, but at least on emulator I’m still getting not-night behavior when Dark theme is set. It is not really clear in the documentation if this user setting is even relevant at all. – Dec 25 '18 at 17:50
-
@ArturDryomov - the Display setting only applies to the launcher, not to third party apps. – ianhanniballake Dec 25 '18 at 18:20
-
thanks! Just created an issue to clarify this behavior for everybody — https://issuetracker.google.com/issues/121997757 – Dec 25 '18 at 20:21
There seems to be a bug in Android Lollipop with AppCompat 23.2.0: Google Issue Tracker
The following code does only work pre-Lollipop:
public class MyApplication extends Application {
static {
AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_YES);
}
[...]
}

- 769
- 9
- 27