AppCompat DayNight theme not work on Android 6.0? AppCompat DayNight theme not work on Android 6.0? xml xml

AppCompat DayNight theme not work on Android 6.0?


Google have fix it in support 23.2.1

Old answer:

On Android 6.0, system's night mode setting defalut is UiModeManager.MODE_NIGHT_NO, it will change Resources.Configuration.uiMode before onCreate is called. However, support library apply its night mode setting in onCreate in AppCompatActivity, it's too late, I think thats why it not work on 6.0.

So if we can Override getResources() in AppCompatActivity and change uiMode.

Old answer:

Here are code to fix not work on Android 6.0

public class Application extends android.app.Application {    static {        AppCompatDelegate.setDefaultNightMode(                AppCompatDelegate.MODE_NIGHT_);    }    @Override    public void onCreate() {        super.onCreate();        // add this code for 6.0        // DO NOT DO THIS. It will trigger a system wide night mode.        // This is the old answer. Just update appcompat.        // UiModeManager uiManager = (UiModeManager) getSystemService(Context.UI_MODE_SERVICE);        // uiManager.setNightMode(UiModeManager.MODE_NIGHT_);    }}

Note: If your app don't have location permission, your app will not have the same calculate result of system. It means it is possible support library thinks it is night now when system not, this will cause some of your UI looks dark some light.

The best way is wait for Google to fix it.


The best solution is to update context with proper config. Here is a snippet of what I do:

public Context setupTheme(Context context) {    Resources res = context.getResources();    int mode = res.getConfiguration().uiMode;    switch (getTheme(context)) {        case DARK:            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);            mode = Configuration.UI_MODE_NIGHT_YES;            break;        case LIGHT:            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);            mode = Configuration.UI_MODE_NIGHT_NO;            break;        default:            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);            break;    }    Configuration config = new Configuration(res.getConfiguration());    config.uiMode = mode;    if (Build.VERSION.SDK_INT >= 17) {        context = context.createConfigurationContext(config);    } else {        res.updateConfiguration(config, res.getDisplayMetrics());    }    return context;}

Then use the context in your Application like so

@Overrideprotected void attachBaseContext(Context base) {    Context context = ThemePicker.getInstance().setupTheme(base);    super.attachBaseContext(context);}


Add getDelegate().applyDayNight(); after setDefaultNightMode.