Search code examples
androidkotlinandroid-themeandroid-night-mode

Refresh the backstack Activities after Night Mode has changed


I have seen a lot of questions and answers about recreating the current activity after changing the application's Night Mode, but I have seen nothing on how to refresh the back stack Activities.

Say I have the backstack A > B > C. Activity C allows to change the night mode by calling AppCompatDelegate.setDefaultNightMode(). After this call, the current Activity (C), can refresh its theme with delegate.applyDayNight() or recreate().

However, when the user navigates back to B or A, the activities are still using the "old" mode, either day or night.

I tried to add something like that to the Activities:

override fun onResume() {
  super.onResume()
  delegate.applyDayNight()
}

But it does not seem to work.

I did multiple attempts to fix this:

One idea would be to recreate the backstack completely like suggested here or here, but since the backstack is not static, it's not doable for me.

Another idea would be to have a class that handles the night mode change and provides a LiveData. Each Activity would listen to the LiveData for a mode change and call recreate(). However, we are stuck in an infinite loop because the Activity would recreate directly after starting to listen to the LiveData.

I find it hard to believe that I am the first one trying to refresh the Activities from the backstack after changing the night mode. What did I miss?

Thanks!


Solution

  • If you can detect when the day/night mode has changed, you can simply recreate an activity that is resumed when the back stack is popped.

    In the following demo, there are three activities: A, B and C. A creates B and B creates C. Activity C can change the day/night mode. When C is popped, activity B sees the change in the day/night mode and calls reCreate() to recreate the activity. The same happens in activity A when activity B is popped.

    The video below shows the effect. The light-colored background is the "day" mode and the dark is "night" mode.

    I have created a GitHub project for this demo app. If this works as a solution, I can incorporate more text into the answer from the project.

    enter image description here