Dark Mode and Theme Customization
# CHAPTER 15
Dark Mode and Theme Customization
1. Introduction
Dark mode is no longer a niche feature for power users; it is an industry-standard expectation. Users love dark themes because they save battery life on OLED screens and reduce eye strain in low-light environments. If your app does not support dark mode gracefully, it will feel outdated. In this chapter, we will learn how Android's theme system works, how to implement theDayNight theme, and how to define color resources so your app looks gorgeous in any lighting condition.
2. Learning Objectives
By the end of this chapter, you will be able to:- Understand how Android's Resource Qualifier system applies to colors.
-
Use the
DayNightMaterial theme.
-
Create a
values-nightdirectory for dark mode colors.
- Prevent hardcoded colors from breaking your UI.
- Understand the basics of Material You (Dynamic Color).
3. The DayNight Theme
To support dark mode, your app's base theme must inherit from a DayNight theme.
Open res/values/themes.xml. It should look something like this:
When using DayNight, Android will automatically switch the default background from white to dark gray, and default text from black to white, based on the user's system settings.
4. Handling Custom Colors (values-night)
While Android handles default backgrounds and text, it doesn't know what to do with your custom colors. If you hardcode a custom background to #EEEEEE (light gray), it will remain bright light gray even in dark mode, blinding the user.
The Solution:
Never hardcode colors in your layout XML. Always reference them from colors.xml.
Then, create a second colors.xml file specifically for dark mode!
- 1. In Android Studio, switch to the "Project" view.
-
2.
Navigate to
res/and create a new directory calledvalues-night.
-
3.
Inside it, create a
colors.xmlfile.
Light Mode (res/values/colors.xml)
Dark Mode (res/values-night/colors.xml)
Now, in your layout XML:
The system will automatically pick the correct color file depending on the active theme!
5. Elevation in Dark Mode
In Light Mode, we use drop shadows (Elevation) to show depth. However, shadows are invisible on a dark background! Material Design solves this brilliantly: in Dark Mode, when you increase the elevation of aMaterialCardView, it doesn't just cast a shadow; the surface color actually gets slightly *lighter*.
You don't have to code this—the MaterialComponents theme handles it automatically, provided you use the default surface colors.
6. Material You and Dynamic Colors (Android 12+)
Starting in Android 12, Google introduced Material You. Instead of the developer picking the primary colors, the OS extracts a color palette from the user's home screen wallpaper and applies it to the app!To support this, you apply the Dynamic Colors API in your Application class:
If dynamic colors are available, the system will override your colorPrimary with the user's chosen wallpaper color, making your app feel deeply personal.
7. Design Principles for Dark Mode
-
Avoid Pure Black: Do not use
#000000for the app background. Use a dark gray like#121212. Dark gray reduces eye strain and allows you to show elevation (a slightly lighter gray card on a dark gray background).
-
Desaturate Colors: Bright, highly saturated colors vibrate visually against dark backgrounds. In your
values-night, provide desaturated, pastel versions of your primary colors.
8. Common Mistakes
-
Hardcoding
#FFFFFFor#000000: If you writeandroid:textColor="#000000"in your layout, that text will be invisible when the background turns dark. Always use?attr/colorOnSurfaceor reference a color resource.
-
Forgetting Vector Icons: If you use a black PNG icon, it will disappear in dark mode. Use Vector Assets and apply
app:tint="?attr/colorControlNormal"so they change color automatically.
9. Best Practices
- Allow the user to override the system setting. Provide a settings toggle in your app: "Light", "Dark", or "System Default".
10. Exercises
-
1.
Create a
values-nightdirectory and acolors.xmlfile inside it.
-
2.
Define a color named
app_backgroundin both the standard and nightcolors.xml. Use a light gray for day, and a very dark blue for night. Apply it to your main layout and toggle the emulator's dark mode to see it change.
11. UI Design Challenges
Challenge: Ensure an onboarding screen's Hero Image looks good in both modes. Using the-night resource qualifier, create a drawable-night folder. Place a dark-themed version of your illustration there, and the light-themed version in the standard drawable folder with the *exact same filename*. The OS will automatically swap the images!
12. MCQ Quiz with Answers
What happens to drop shadows on elevated MaterialCardViews in a dark theme?
Which resource directory should you create to hold color values specifically for dark mode?
13. Interview Questions
-
Q: Why is it recommended to use
#121212(dark gray) instead of#000000(pure black) for dark mode backgrounds?
-
Q: What does the
DayNighttheme do under the hood?
- Q: Explain how you would allow a user to manually toggle Dark Mode from within your app's settings.
14. FAQs
Q: Will implementing Dynamic Colors ruin my brand identity? A: It depends. If your app heavily relies on strict brand colors (like a banking app), you might opt out of Dynamic Colors. If your app is a utility or content app, adopting the user's wallpaper colors provides a highly modern, integrated feel.15. Summary
Supporting Dark Mode is an absolute requirement for modern Android apps. By avoiding hardcoded hex values, utilizing theDayNight theme, and leveraging the values-night resource qualifier, we can create UI designs that adapt beautifully to the user's environment and preferences.