Android dark mode developer

How to implement a dark theme on Android

Android 10 adds a system-wide dark theme, which preserves battery power for devices with OLED screens, reduces eye strain, and facilitates use in low-light environments.

These guidelines will show you how to implement a dark theme on Android, even on earlier versions of the platform.

1. Declare dependencies

Add the following dependencies to your project:

2. Inherit from a DayNight theme

The easiest way to support a dark theme is to inherit from a DayNight theme such as Theme.AppCompat.DayNight .

Basically, a DayNight theme is composed of a Light theme in the values directory and a Dark theme in the values-night directory.

For example, declare a Theme.MaterialComponents.DayNight.NoActionBar.Bridge :

And then, declare your AppTheme :

3. Use theme attributes for colors

When writing your layouts, use theme attributes or night-qualified resources instead of hard-coded colors to ensure that they display suitable colors in a Light theme and in a Dark theme.

For example, when you use a FloatingActionButton , the default backgroundTint is ?attr/colorAccent so the tint should be ?android:attr/textColorPrimaryInverse to ensure that the contrast ratio between the icon and its background is eligible:

In a Light theme, it will display a #ffffffff icon on a #ff009688 background.

In a Dark theme, it will display a #de000000 icon on a #ff80cbc4 background.

4. Allow users to change the app’s theme

Your app should let the user switch between themes, which map directly to one of the following modes:

Use AppCompatDelegate.setDefaultNightMode to switch the theme for all components in your app. Please note that it is not saved when the app is killed so you should use Settings to save the user’s choice.

For example, use the following code in your Activity to change the night mode:

And then, use the following code in your Application to restore the night mode:

5. Run your app

That’s it, you are ready to run your app and enjoy a dark theme!

Sample

For a complete example, check out my sample on GitHub.

Источник

DayNight — Adding a dark theme to your app

This post has been updated multiple time since first publishing. The content is correct as-of April 26th 2019.

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.

How do I use it?

You need to change your theme to extend from one of the DayNight variants, and then call one method to enable the feature. Here’s an example theme declaration:

If you’re using Material Design Components (and I recommend you to do so), then you can also use the Theme.MaterialComponents.DayNight theme from their v1.1.0 release. The rest of this post remains the same.

You then need to enable the feature in your app using one of the APIs provided.

setDefaultNightMode

The first API we provide to do that is AppCompatDelegate.setDefaultNightMode() , which takes one of the follow values:

  • MODE_NIGHT_NO . Always use the day (light) theme.
  • MODE_NIGHT_YES . Always use the night (dark) theme.
  • MODE_NIGHT_FOLLOW_SYSTEM (default). This setting follows the system’s setting, which on Android Q and above is a system setting (more on this below).
  • MODE_NIGHT_AUTO_BATTERY . Changes to dark when the device has its ‘Battery Saver’ feature enabled, light otherwise.
    ✨ New in v1.1.0-alpha03.
  • MODE_NIGHT_AUTO_TIME & MODE_NIGHT_AUTO . Changes between day/night based on the time of day.
    ⛔ Deprecated in v1.1.0-alpha03.
Читайте также:  Удаленный рабочий стол anydesk для андроид

The method is static so you can call it at any time. The value you set is not persisted across process starts though, therefore you need to set it every time your app process is started. I recommend setting it in your application class (if you have one) like so:

From AppCompat v1.1.0-alpha05 onwards, setDefaultNightMode() will automatically apply any DayNight changes to any ‘started’ Activities. This means that you no longer have to manually recreate any Activities when you call the API.

setLocalNightMode

You can also override the default value in each component with a call to its AppCompatDelegate’s setLocalNightMode() . This is handy when you know that only some components should use the DayNight functionality, or for development so that you don’t have to sit and wait for night to fall to test your layout.

Using this method in every Activity is now an anti-pattern, and you should move to using setDefaultNightMode() instead. See the section below for the technical details to why.

Activity recreations

Both of the methods mentioned above will recreate your Activity if a Configuration change is required, so that the new theme can be applied. This is a good opportunity to test whether your Activity + Fragments save their instance state correctly.

How can I check what configuration I’m currently in?

You can do this by checking your resource configuration:

WebViews

There is currently one big caveat to using this feature: WebViews. Since they can not use theme attributes, and you rarely have control over any web content’s styling, there is a high probability that your WebViews will be too contrasting against your dynamic themed app. So make sure you test your app in both modes to ensure that it’s not annoying to the user.

System night mode

Android Q onwards has a system night mode which can be enabled in the Settings app. Android Pie also has a system night mode setting, but it is only surfaced in the device’s ‘developer options’. For ease, I recommend treating Android Pie the same as previous versions of Android.

In-app setting

It is recommended to provide a way for the user to override the default theme in your app. The recommended options and strings are:

  • ‘Light’ ( MODE_NIGHT_NO )
  • ‘Dark’ ( MODE_NIGHT_YES )
  • ‘Set by Battery Saver’ ( MODE_NIGHT_AUTO_BATTERY ).
    Only show on Android Pie and below. This should be your app’s default when shown.
  • ‘Use system default’ ( MODE_NIGHT_FOLLOW_SYSTEM ).
    Only show on Android Q and above. This should be your app’s default when shown.

A common way to do to implement would be via a ListPreference, calling to setDefaultNightMode() when the value changes.

Updating your themes + styles

As well as calling AppCompat, you will likely need to do some work to update your themes, styles and layouts so that they work seamlessly across both dark and light themes.

The rule-of-thumb for these things is to always use theme attributes when you can. Here are the most important to know about:

  • ?android:attr/textColorPrimary . General purpose text color. Will be near-black on light theme, near-white on dark themes. Contains a disabled state.
  • ?attr/colorControlNormal . General-purpose icon color. Contains a disabled state.

Using Material Design Components also makes this a lot easier, as it’s attributes (such as ?attr/colorSurface and ?attr/colorOnSurface ) provide you an easy generalized themed color to use. These attributes of course can be customized in your theme.

Using your own resources for dark/light

AppCompat in simple terms is just enabling the use of the night and notnight resource qualifiers. These have actually been available in the platform since API 8, but were previously only used in very specific scenarios.

Читайте также:  Операционна система symbian или android

Under the hood Theme.AppCompat.DayNight is implemented as so:

This means that you can also provide alternative resources for your light and dark UIs. Just use the — night qualifier on your resource folders: drawable-night , values-night , etc.

Why should I move to using setDefaultNightMode?

In AppCompat v1.1.0, DayNight had a big rewrite in order to fix a number of bugs. The biggest bug was this:

  • WebView would reset the Activity configuration as soon as it was loaded into the process. This could lead to later inflated views using the wrong theme.

AppCompat needs to change the Activity’s resources configuration to enable “night mode”. The problems with WebView stemmed from using a now deprecated method: Resources.updateConfiguration() to achieve that. Unfortunately WebView doesn’t work very well with that method (hence the deprecation).

The rewrite focused on moving to a newer method to update the configuration: ContextThemeWrapper.applyOverrideConfiguration() . Unfortunately, that API is a lot more tricky to use since it can only be called before any call to getResources() . It turns out getResources() is called a lot, and gets called very early on in the Activity lifecycle. In fact the only place I found where it could be called safely is in attachBaseContext() , which is a lot earlier than onCreate() .

OK, I’ve just told you a lot of technical stuff about the internals of DayNight, so what does that have to do with setDefaultNightMode() ? Well because we can only call applyOverrideConfiguration() in attachBaseContext() , this gives us a very small window for setLocalNightMode() to work without having to recreate the Activity.

Previously you could do the following quite happily, without AppCompat needing to recreate the Activity:

Due to what we’ve spoken about above, that will now trigger a recreation in the new version of DayNight. In fact, any call to setLocalNightMode will trigger a recreation (if the theme changes).

This is the crux of why you should now prefer setDefaultNightMode() , to minimize unnecessary recreations. Since it’s a static method, the value is always available, and isn’t beholden to the Activity lifecycle. The method models what most apps want to do anyway, which is provide an app-wide setting or preference.

That doesn’t mean that setLocalNightMode is wrong to use, just use it for what it is meant for: one-off overrides in individual Activities.

Источник

How to Implement Dark Mode in Android

January 29, 2021

In the recent past, there has been a lot of excitement regarding dark mode. Users can change the entire look and feel of their application with a click of a button. Numerous developers and huge companies such as Google, Facebook, and Twitter have already implemented this feature in their applications.

Introduction

The dark mode feature does not need any significant explanation. It’s highly likely that you have already used dark mode on your phone or computer at one point. So, we can simply define dark mode as a setting that changes the overall color of your application to black. The dark mode is supported by both mobile and web applications.

Many applications on the Google Play Store are already equipped with this feature. There are even rumors that enabling dark mode helps prolong battery life. Furthermore, it improves the visual appeal of the app, especially for those users with eye problems.

To incorporate the dark mode feature into an Android Application using Kotlin.

Prerequisites

This tutorial is suitable for intermediate learners. Therefore, you must be familiar with the Kotlin programming language, as well as the file or project structure in Android studio.

When it comes to programs, you will need Android Studio installed on your computer. Having a physical Android device is also recommended. This is because we will test the application on our phones.

Creating the project

Open Android Studio and create a new project. You can give it any name. In my case, the project is called darkmode . Then, select an Empty Activity and proceed to the next screen.

In this window, ensure that you set the minimum SDK as API 21 OR Lollipop. You can then click finish and wait for the project to be set up. This usually takes a few minutes depending on your internet connection. Note: That we do not need to install any other dependencies for this tutorial.

Creating the attrs.xml file

We need to declare our color attributes in an attrs.xml file. We will later access our settings from this file rather than the default colors.xml . In the res/values folder, create a new resource file and name it attrs.xml . Add the following code in this file.

Читайте также:  Тотал вар андроид без лицензии

Here allows us to add the style attributes of our app. As shown in the code snippet, the app will have elements such as background_color , text_color , and button_color . Ensure that all of these attributes have the color format.

Modifying the style.xml file

We need to add our light and dark themes in the styles.xml .

When you open this file, you will realize that there is a pre-existing style named AppTheme . This will serve as our light theme. We then add the dark theme style below the AppTheme . The next step is to incorporate the elements in the attrs.xml file in both themes. This is shown below.

Kindly note that the dark theme should already have all the elements described in the light theme but with different colors.

Creating the UI

In this tutorial, our app will have a simple user interface. The UI will include a switch and a textview. To get started, open the activity_main.xml . Change the layout from ConstraintLayout to LinearLayout .

Remember to set the orientation as vertical. Next, add a Switch and TextView widgets and position them at the center of the page. Finally, include an id to the Switch widget.

Here is the full code for the activity_main.xml .

Remember to set the color of the UI components. As noted, we will access our colors via the attrs.xml file we created earlier. We, therefore, use «?attr/text_color» to set color to our widgets. Your application will not work if you ignore this crucial aspect.

Checking state and handling click events

Whenever our app starts, we need to check which theme is enabled by default. We do this by using the AppCompatDelegate class. Here is the code snippet to check the app’s theme.

Please note that you should include the code snippet above immediately after the onCreate function or before the activity_main.xml layout is initialized.

Next, we need to handle the click events for our Switch. Remember, we had assigned this component with the id of switchtheme . We, therefore, use this id to listen for changes as shown below.

The isChecked is a Boolean variable. When is isChecked is true, it means that we need to enable the dark theme. This is done using the below code snippet.

We set the default light theme as shown below.

Here is the code for the MainActivity.kt .

If you have followed the above steps properly, your app should now have a dark mode. The following gif shows the dark mode in action.

.

Conclusion

Dark mode is indeed a fun thing to implement in our mobile applications. I hope that this tutorial has equipped you with the required skills and knowledge to work on dark themes. In case you haven’t understood anything, feel free to revisit the above steps.

Peer Review Contributions by: Peter Kayere

About the author

A lover of technology. An upright individual not afraid of getting out of the comfort zone and trying out new things.

Want to learn more about the EngEd Program?

Discover Section’s community-generated pool of resources from the next generation of engineers.

Источник

Оцените статью