Rich Browne
Rich Browne

Reputation: 323

DayNight theme doesn't follow system

I've implemented a theme whose parent is Theme.AppCompat.DayNight and assigned it to my activity. If my app is stopped and I change the system theme to dark mode then start my app, the dark theme works correctly. However, if I then turn system dark mode off whilst my app is running it does not switch themes until I restart the app.

I can see that other apps that support dark themes change immediately whilst running as soon as I press the system dark mode button.

What am I missing here?

Upvotes: 1

Views: 969

Answers (1)

cactustictacs
cactustictacs

Reputation: 19524

Ok, so the way it works is the DayNight theme automatically switches between themes, either when you set a different one with AppCompatDelegate.setDefaultNightMode() or (setLocalNightMode) or (I'm assuming) when you're following the System setting, and the system sends out a "ok use night mode now" message

The way it "switches" is by recreating Activities, using the appropriate variation on the theme. Here's one of the devs explaining it:

Activity recreations Both of the methods mentioned above will recreate your Activity if a Configuration change is required, so that the new theme can be applied. This is a good opportunity to test whether your Activity + Fragments save their instance state correctly.

The problem is, you're overriding those configuration changes instead of letting the system handle it. You're basically saying "don't worry, if the Activity needs recreating for any of these reasons, don't do it - I'll take care of it". But this is complicated, and it's recommended that you don't do that

Caution: Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.

So by including those overrides, you're blocking the system from applying the changes. It works when you restart the app because then it gets to (re)create the Activity and set it up with the right styling and resources.

I'm guessing removing the overrides causes problems because you've been relying on them to stop Activities being recreated, so you don't have the code in place to save state and rebuild everything. (This is the reason a lot of people add the overrides in the first place, it's a hack to make their lives easier, but it causes problems like this!)

If that's your issue you'll have to rework parts of your app to save and restore state when an Activity is destroyed, but it's better that it can handle this stuff anyway - avoids things randomly being blank when they come back from the background, etc.

Upvotes: 1

Related Questions