Tutorial

Android DayNight Theme for Night Mode in App

Published on August 3, 2022
author

Anupam Chugh

Android DayNight Theme for Night Mode in App

In this tutorial, we’ll be discussing and using the Android DayNight theme in our application. If you have an app with reading materials then having night mode is helpful for ease of eyes.

Android DayNight Theme

Android released a new theme: Theme.AppCompat.DayNight with the support library 23.2.0. Thanks to this theme, we can now toggle between the light and dark modes of our application. We can do so manually or let Android detect the time of the day implicitly from your phone. This theme enhances the readability and usability of your application during the night by replacing the white flashy background with a darker one. Many reader applications have already deployed this theme in their apps. Let’s get started with our implementation by creating a new Android Studio project with empty activity.

Adding the theme to our styles.xml

Let’s replace the current theme in our application with the DayNight one.

<style name="AppTheme" parent="Theme.AppCompat.DayNight">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

To set the DayNight theme in our application we use the method: AppCompatDelegate.setDefaultNightMode() Following are the arguments allowed in the above method.

  • MODE_NIGHT_YES – Enables night mode manually.
  • MODE_NIGHT_NO – Disables night mode manually.
  • MODE_NIGHT_FOLLOW_SYSTEM – Uses the system settings to determine the time of day and toggles NightMode accordingly. This is the default argument.
  • MODE_NIGHT_AUTO – This tries to auto-detect the time from the device location APIs. If the runtime permission for location services isn’t granted, then it uses the system time.

Add the following code in the onCreate() method.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); //For night mode theme
        //AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); //For day mode theme
        setContentView(R.layout.activity_main);
    }

The theme should always be set before the setContentView method is invoked.

What is AppCompatDelegate?

An AppCompatDelegate is a class represents a delegate which you can use to extend AppCompat’s support to any Activity. Let’s see how our activity screen looks like with the day mode and night mode enabled one by one. android day mode android night mode The TextView changes its color to white in the night mode. This is since the TextView implicitly contains the default style named : ?attr/colorPrimary which toggles the color based on the light/dark app theme. If you set a custom color @color/red on the TextView, it won’t change between day/night modes. The Toolbar text color in the day mode is black. How to set it to white in the styles.xml itself?

<style name="AppTheme" parent="Theme.AppCompat.DayNight">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textColorPrimary">@android:color/white</item>
        <item name="android:textColorSecondary">@android:color/white</item>
    </style>

To retrieve the current night mode type we use the method AppCompatDelegate.getDefaultNightMode() which returns an integer for each of the types discussed earlier, respectively. Having got a basic idea let’s make an application which will:

  • Customise resources, styles in day/night modes.
  • Toggle DayNight theme from the UI
  • See how various UI widgets look in Night Mode.

Android Night Mode Project Structure

android daynight theme example project

Android DayNight Theme Example Code

The code for the activity_main.xml class file is given below.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_margin="@android:dimen/app_icon_size"
        android:text="Welcome to this tutorial."
        android:textColor="@color/daynight_textColor"
        android:textSize="18sp" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:layout_centerInParent="true"
        android:src="@drawable/placeholder" />


    <TextView
        android:id="@+id/txtNightMode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/switchCompat"
        android:layout_centerHorizontal="true"
        android:paddingRight="8dp"
        android:text="Night Mode"
        android:textColor="@color/daynight_textColor" />


    <android.support.v7.widget.SwitchCompat
        android:id="@+id/switchCompat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="@android:dimen/app_icon_size"
        android:layout_toRightOf="@+id/txtNightMode"
        android:checked="false"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/imageView"
        android:layout_alignLeft="@+id/txtNightMode"
        android:layout_alignStart="@+id/txtNightMode"
        android:text="CLICK ME"
        android:textColor="@color/daynight_textColor" />
</RelativeLayout>
  • We’ve set a custom text color and drawable on the ImageView.
  • To set different colors and drawables for day and night themes, we need to create separate folders for the resources.
  • The day theme resources reside in the default directory.
  • The night theme resources reside in folders with names appended with -night.
  • Hence we’ve created values-night and drawable-night folders in our project.
  • The drawable filename, colors, style names must be the same in both the directories for the resources you wish to toggle in DayNight theme.
  • If the above things are defined in only one of the directories, the same would be used in day and night themes.

The code the styles.xml in values and values-night folders are given below.

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.DayNight">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textColorPrimary">@android:color/white</item>
    </style>

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

    <style name="MySwitch">
        <item name="colorControlActivated">@color/switchColor</item>
    </style>
</resources>
<resources>
    <!-- Base application theme. values-night.xml -->
    <style name="AppTheme" parent="Theme.AppCompat.DayNight">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/orange</item>
        <item name="colorPrimaryDark">@color/orangeDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textColorPrimary">@android:color/white</item>
    </style>

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

    <style name="MySwitch">
        <item name="colorControlActivated">@color/switchColor</item>
    </style>
</resources>

The styles defined above are used to set customise the standard DayNight theme. The respective things for the colors.xml are defined as shown below. [caption id=“attachment_19359” align=“aligncenter” width=“457”]android daynight colors night modecolors.xml from values-night folder[/caption] [caption id=“attachment_19360” align=“aligncenter” width=“434”]android daynight colors day modecolors.xml from values folder[/caption] The code for the MainActivity.java class is given below.

package com.journaldev.daynightmode;

import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.SwitchCompat;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (InitApplication.getInstance().isNightModeEnabled()) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        } else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        }
        setContentView(R.layout.activity_main);


        SwitchCompat switchCompat = findViewById(R.id.switchCompat);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new AlertDialog.Builder(MainActivity.this, R.style.MyDialog)
                        .setTitle("Title")
                        .setMessage("Message")
                        .show();
            }
        });

        if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES)
            switchCompat.setChecked(true);

        switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    InitApplication.getInstance().setIsNightModeEnabled(true);
                    Intent intent = getIntent();
                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                    finish();
                    startActivity(intent);

                } else {
                    InitApplication.getInstance().setIsNightModeEnabled(false);
                    Intent intent = getIntent();
                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                    finish();
                    startActivity(intent);
                }


            }
        });

    }
}

In the above code we use the Switch to toggle between the day and night mode themes in our application. We save the current mode in a SharedPreferences object. WHY? The theme of an activity can be set only once. Hence when the switch is toggled, we need to save the new mode in a SharedPreference object. We use the Singleton Pattern for Application class. This way the same instance of Application class can be used throughout the application. The code for the InitApplication.java class is given below.

package com.journaldev.daynightmode;

import android.app.Application;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;


public class InitApplication extends Application {
    public static final String NIGHT_MODE = "NIGHT_MODE";
    private boolean isNightModeEnabled = false;

    private static InitApplication singleton = null;

    public static InitApplication getInstance() {

        if(singleton == null)
        {
            singleton = new InitApplication();
        }
        return singleton;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        singleton = this;
        SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
        this.isNightModeEnabled = mPrefs.getBoolean(NIGHT_MODE, false);
    }

    public boolean isNightModeEnabled() {
        return isNightModeEnabled;
    }

    public void setIsNightModeEnabled(boolean isNightModeEnabled) {
        this.isNightModeEnabled = isNightModeEnabled;

        SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor = mPrefs.edit();
        editor.putBoolean(NIGHT_MODE, isNightModeEnabled);
        editor.apply();
    }
}

It is here where we update and retrieve the night mode type from the Shared Preferences.

Android Night Mode Support App Output

android daynight theme output You can download the final Android DayNight Mode Project from the link below.

Download Android DayNight Theme Example Project

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Anupam Chugh

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
December 24, 2021

I’m having trouble in handling Dark mode with my app targeting SDK 31. If the system is in light mode and my app is in dark mode then the app crashes on start up without any clue. Please help!!!

- Anupam Bhardwaj

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    June 21, 2021

    How it work’s in app overlay’s which comes when app killed. How overlay dialog display according to theme

    - Richa

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      June 11, 2020

      Hey am using recyclerview with cardview but in night mode card view theme change at first than after 2-3 attempt it turns to white again please do this with Recyclerview too

      - monika sharma

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        May 5, 2020

        I want to change the whole application theme change on toggle but what can I do?

        - Kailas mantri

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          October 18, 2019

          Don’t forget to put (android:allowBackup=“true”) inside application on AndroidManifest file for avoid: java.lang.NullPointerException: Attempt to invoke virtual method ‘java.lang.String android.content.Context.getPackageName()’ on a null object reference

          - Mazharul Islam

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            August 7, 2019

            Can we apply or change dark theme after applying config changes for an activity?

            - Raj

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              July 11, 2019

              You can use the recreate() method (from AppCompatActivity) to refresh the activity after changing the setting. You can also do something like this to force the activity tp update: @Override protected void onResume() { … read in the setting mode, if it’s changed the recreate will be called. if (AppCompatDelegate.getDefaultNightMode() != defaultMode) { recreate(); } super.onResume(); }

              - ken

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                May 13, 2019

                I used maually night mode and disable but in Night mode fragment creating issue on screen rotation but work fine in day theme mode.

                - Abhishek

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  May 13, 2019

                  issue on fragment screen rotation

                  - Abhishek

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    March 29, 2019

                    how to switch on the theme on resume activity

                    - Neeraj

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Featured on Community

                      Get our biweekly newsletter

                      Sign up for Infrastructure as a Newsletter.

                      Hollie's Hub for Good

                      Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

                      Become a contributor

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      Welcome to the developer cloud

                      DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Learn more