17

I am using the new Theme.AppCompat.DayNight added in Android Support Library 23.2

On Android 5.1 it works well.

On Android 6.0, activity looks like using light theme, but dialog looks using dark theme.

My Application class:

public class MyApplication extends Application {
    static {
        AppCompatDelegate.setDefaultNightMode(
                AppCompatDelegate.MODE_NIGHT_YES);
    }
}

My styles.xml

<style name="AppTheme" parent="Theme.AppCompat.DayNight">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

<style name="Dialog.Alert" parent="Theme.AppCompat.DayNight.Dialog.Alert"/>

My code to show a dialog:

new AlertDialog.Builder(mContext, R.style.Dialog_Alert)
                .setTitle("Title")
                .setMessage("Message")
                .show();
Amit Vaghela
  • 22,772
  • 22
  • 86
  • 142
Rikka
  • 461
  • 4
  • 12

6 Answers6

7

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.

Kevin TeslaCoil
  • 10,037
  • 1
  • 39
  • 33
Rikka
  • 461
  • 4
  • 12
  • It did work. The key I guess is to make sure to call UiModeManager #setNightMode before AppCompatDelegate#applyDayNight. – mariotaku Feb 29 '16 at 15:05
  • 3
    Don't do this. There is no need to force the entire system to use night mode so that you can use it in your app. Wait for the 23.2.1 bugfix release. (source: I'm the lead engineer for the support library) – alanv Mar 01 '16 at 17:32
  • Could please let us know when the bugfix released will be published if the decision has been made? – Tony Thompson Mar 01 '16 at 22:59
5

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

@Override
protected void attachBaseContext(Context base) {
    Context context = ThemePicker.getInstance().setupTheme(base);
    super.attachBaseContext(context);
}
Valentin Baryshev
  • 2,195
  • 3
  • 15
  • 24
3

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

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
shnizlon
  • 1,486
  • 1
  • 11
  • 8
3

This issue was reported on https://code.google.com/p/android/issues/detail?id=201910

But after release of Android Support Library, revision 23.2.1 (March 2016). This issue has been resolved.

Fixed a compatibility issue with Night Mode and API level 23

update Support Library to Android Support Library to 23.2.1

Amit Vaghela
  • 22,772
  • 22
  • 86
  • 142
2

As of now, no Gradle dependency is needed to enable the night mode other than androidx.appcompat:appcompat:1.0.2 which will already be present. Make sure to change the default theme from Theme.AppCompat.Light.DarkActionBar to Theme.AppCompat.DayNight.DarkActionBar in the styles.xml file and then do AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) to switch to the night mode. I have tested it in APIv23(Android 6.0) and above and it is working fine. For a better explanation see this codelab by Android

Neeraj Sewani
  • 3,952
  • 6
  • 38
  • 55
1

just add this in your values-v21

<style name="Theme.AppCompat.DayNight">

work for me done.

AAAAAA
  • 21
  • 2