Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AppCompat DayNight theme always appears as a Light theme?

I am using the new Theme.AppCompat.DayNight theme of AppCompat introduced in version 23.2, but instead of switching between a day (light) and night (dark) theme automatically, it always appears as a light theme. How can I get it to switch to a dark theme?

like image 741
ianhanniballake Avatar asked Feb 26 '16 00:02

ianhanniballake


People also ask

How do I use the appcompat support library for themes?

The AppCompat support library provides themes to build apps with the Material Design specification. A theme with a parent of Theme.AppCompat is also required for an Activity to extend AppCompatActivity. The first step is to customize your theme’s color palette to automatically colorize your app. In your app's res/styles.xml you can define:

What is the DayNight functionality in appcompat?

The DayNight functionality in AppCompat allows your app to easily switch between a dark ⚫ and light ⚪ theme. This has many benefits for your users, from saving power on OLED displays, to increasing usability for people with reduced-vision, and more.

What is the use of appcompat in Android?

What is use in Android? The AppCompat support library provides themes to build apps with the Material Design specification. A theme with a parent of Theme.AppCompat is also required for an Activity to extend AppCompatActivity.

Why doesn’t the applicationcontext have my app theme?

The ApplicationContext doesn’t have your app theme. You need to pass the Activity, not an Application Context.


2 Answers

As specified in that same 23.2 blog post,

By default, whether it is ‘night’ will match the system value (from UiModeManager.getNightMode())

However, as of now, this effectively means that it is equivalent to MODE_NIGHT_NO as the only thing that triggers night mode are car docks from the Gingerbread era.

This means that on current devices, the only way to see a dark theme when using a DayNight theme is to use NIGHT_MODE_YES or NIGHT_MODE_AUTO

As stated in both the official post and Chris Banes' post on DayNight, you can change the mode at either the global level or the local level.

The global level relies on the static AppCompatDelegate.setDefaultNightMode() method, which sets the DayNight mode across your entire app. As this only applies while your process is alive (i.e., it is only an in memory flag), you need to make sure you set it every time your application is started. One recommended approach from Chris' post to do that is to set it in a static method of your custom Application class:

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

If, instead, you only want to change the mode for a single activity/dialog, you can instead call getDelegate().setLocalNightMode():

public class MyActivity extends AppCompatActivity {
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState == null) {
      // Set the local night mode to some value
      getDelegate().setLocalNightMode(
                AppCompatDelegate.MODE_NIGHT_...);
      // Now recreate for it to take effect
      recreate();
    }
  }
}

This changes just the single instance - you'll note the call to recreate() - Views that have already been inflated won't be affected by a change in night mode, so you can force the activity to recreate itself to get the updated values.

Of course, Chris' post also states

Also remember that the default is MODE_NIGHT_FOLLOW_SYSTEM, so if we add a user-visible setting to the platform in the future, AppCompat will automatically use it.

like image 104
ianhanniballake Avatar answered Sep 23 '22 07:09

ianhanniballake


There seems to be a bug in Android Lollipop with AppCompat 23.2.0: Google Issue Tracker

The following code does only work pre-Lollipop:

public class MyApplication extends Application {
    static {
    AppCompatDelegate.setDefaultNightMode(
        AppCompatDelegate.MODE_NIGHT_YES);
    }
    [...]
}
like image 28
kroegerama Avatar answered Sep 23 '22 07:09

kroegerama