Reputation: 2228
AppCompatDelegate.MODE_NIGHT_AUTO is not updating my existing activity and I'm not sure why.
I dynamically allow the user to change night mode. If the user changes the mode to auto I set the default night mode then recreate the activity:
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
recreate();
If I change to MODE_NIGHT_YES or MODE_NIGHT_NO, it works as expected. If I change to MODE_NIGHT_AUTO, it goes to the correct dark/light theme, but then it fails to update the activity after the transition from day to night. It kind of sucks to test this because I have to wait for sunrise/sunset (EDIT: apparently I can manually change the time on the device rather than having to wait...so long as the location permission is not used).
Do I have to do a manual check for the night mode flag in onresume and manually update resources for existing activities, or am I doing something wrong? If I rotate the device and the activity is recreated after sunset then the dark theme is correctly picked up, but before rotation it will still be showing the light theme.
Support lib 23.4.0, Android version 6.0.
Upvotes: 6
Views: 3807
Reputation: 11074
It's been fixed in AppCompat 24.2.0. Revision history lists this as a "behaviour change" for 24.2.0:
If you use the appcompat library's day/night functionality, the system now automatically recreates your activity whenever the day/night mode changes (either because of the time of day, or because of a call to AppCompatDelegate.setLocalNightMode()).
Upvotes: 2
Reputation: 2228
In case anyone else wants to know what I did to solve this (not sure if it is the right way to do it though):
private int mCurrentNightMode;
@Override
protected void onCreate(Bundle savedInstanceState) {
mCurrentNightMode = getCurrentNightMode();
}
@Override
protected void onPostResume() {
super.onPostResume();
if (hasNightModeChanged()) {
delayedRecreate();
}
}
private void delayedRecreate() {
Handler handler = new Handler();
handler.postDelayed(this::recreate, 1);
}
private boolean hasNightModeChanged() {
getDelegate().applyDayNight();
return mCurrentNightMode != getCurrentNightMode();
}
private int getCurrentNightMode() {
return getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
}
Upvotes: 4