An Android Material Design 3 Theming and Dynamic Color Tutorial

This chapter will show you how to create a new Material Design 3 theme using the Material Theme Builder tool and integrate it into an Android Studio project. The tutorial will also demonstrate how to add support for and test dynamic theme colors to an app.

Creating the ThemeDemo Project

Select the New Project option from the welcome screen and, within the resulting new project dialog, choose the Basic Activity (Material3) template before clicking on the Next button.

Enter ThemeDemo into the Name field and specify com.ebookfrenzy.themedemo as the package name. Before clicking on the Finish button, change the Minimum API level setting to API 26: Android 8.0 (Oreo) and the Language menu to Kotlin.

Preparing the Project

For this example, we will not be using most of the structure provided by the Basic Activity template. Since this is only a sample app, we can quickly modify it for our needs as follows:

  1. Open the res -> layout -> content_main.xml file, then select and delete the nav_host_fragment_content_main child of the ConstraintLayout entry in the Component Tree panel as shown in Figure 93-1:

Figure 93-1

  1. Edit the MainActivity.kt file and delete the following lines from the onCreate() method:
  val navController = findNavController(R.id.nav_host_fragment_content_main)
  appBarConfiguration = AppBarConfiguration(navController.graph)
  setupActionBarWithNavController(navController, appBarConfiguration)
  1. Remaining in the MainActivity.kt file, delete the onSupportNavigateUp() method.

Designing the User Interface

The main activity will consist of a simple layout containing a Button and the existing Floating Action Button. The layout will be designed within the content_main.xml file which currently contains a ConstraintLayout parent. Open this file in the layout editor and drag and drop a Button view so that it is positioned in the center of the layout canvas so that the layout resembles that shown to the left in Figure 93-2:

Figure 93-2

Compile and run the app on a device or emulator and note the default colors used on the Button and Floating Action Button. The next step is to build a new theme for our project.

Building a New Theme

The theme for the project will be designed and generated using the Material Theme Builder. Open a browser window and navigate to the following URL to access the builder tool:

https://material-foundation.github.io/material-theme-builder/

Once you have loaded the builder, select the Custom button at the top of the screen and then click on the Primary color circle in the Core Colors section to display the color selector. From the color selector, choose any color you feel like using as the basis for your theme:

Figure 93-3

Review the color scheme in the Your Theme panel and make any necessary color adjustments using the Core Color options until you are happy with the color slots. Once the theme is ready, click on the Export button in the top right-hand corner and select the Android Views (XML) option. When prompted, save the file to a suitable location on your computer filesystem. The theme will be saved as a compressed file named material-theme.zip.

Using the appropriate tool for your operating system, unpack the theme file which should contain the following folders and files in a folder named material-theme:

  • values/colors.xml – The color definitions.
  • values/themes.xml – The theme for the light mode.
  • values-night/themes.xml – The theme for dark mode. Now that the theme files have been generated, they need to be integrated into the Android Studio project.

Adding the Custom Colors to the Project

The first step is to replace the current colors.xml file with the new one generated by the Material Theme Builder. Within the Project tool window, select the res -> values -> colors.xml file, tap the keyboard delete key and click on the OK button in the confirmation dialog to remove it from the project.

Open the filesystem navigation tool for your operating system, locate the colors.xml file in the values folder of the new material theme and copy and paste it into the values folder within the Project tool window.

Merging the Custom Themes

Now that we have added our custom theme colors to the project, the next step is modify the themes.xml files to reflect the new theme. The values -> themes -> themes.xml currently reads as follows:

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Base.Theme.ThemeDemo" parent="Theme.Material3.DayNight.NoActionBar">
        <!-- Customize your light theme here. -->
        <!-- <item name="colorPrimary">@color/my_light_primary</item> -->
    </style>

    <style name="Theme.ThemeDemo" parent="Base.Theme.ThemeDemo" />
</resources>

We now need to edit this file and place our new theme item declarations in the area marked <!– Customize your light theme here. –>. Using the Android Studio File -> Open… menu option and open the themes.xml file located in the values folder of your custom theme folder. Once loaded, highlight and copy all of the content between the following elements:

<resources>
    <style name="AppTheme" parent="Theme.Material3.Light.NoActionBar">

          <!-- Copy all elements listed here -->

  </style>
</resources>

Return to the res -> values -> themes -> themes.xml file and paste the content in place of the <!– Customize your light theme here. –> comment lines as follows:

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Base.Theme.ThemeDemo" parent="Theme.Material3.DayNight.NoActionBar">
        <item name="colorPrimary">@color/md_theme_light_primary</item>
        <item name="colorOnPrimary">@color/md_theme_light_onPrimary</item>
        <item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item>
.
.
    </style>

    <style name="Theme.ThemeDemo" parent="Base.Theme.ThemeDemo" />
</resources>

If the colorInversePrimary and colorShadow items are displayed in red indicating they are unresolved, delete these lines from the file before continuing. This is caused by a mismatch between the Android implementation of MD3 and the resources generated by the Material Theme Builder

Repeat the above steps to merge the items from the themes.xml file located in the values-night custom theme folder into the themes.xml (night) file.

Run the app once again to confirm that the Button and Floating Action Button are rendered using the new theme colors.

Enabling Dynamic Color Support

To test dynamic colors the app will need to be run on a device or emulator running Android 12 or later with the correct Wallpaper settings. On the device or emulator, launch the Settings app and select Wallpaper & style from the list of options. On the wallpaper settings screen click the option to change the wallpaper (marked A in Figure 93-4) and select a wallpaper image containing colors that differ significantly from the colors in your theme. Once selected, assign the wallpaper to the Home screen.

Return to the Wallpaper & styles screen and make sure that the Wallpaper colors option is selected (B) before trying out the different color scheme buttons (C). As each option is clicked the wallpaper example will change to reflect the selection:

Figure 93-4

A Material Design 3 Theming and Dynamic Color Tutorial To enable dynamic colors, we need to make a call to the applyToActivitiesIfAvailable() method of the DynamicColors class. To enable dynamic color support for the entire app, this needs to be called from within the onCreate() method of a custom Application instance. Begin by adding a new Kotlin class file to the project under app -> java -> com -> ebookfrenzy -> themedemo named ThemeDemoApplication.kt and modifying it so that it reads as follows:

package com.ebookfrenzy.themedemo
 
import android.app.Application
import com.google.android.material.color.DynamicColors
 
class ThemeDemoApplication: Application() {
    override fun onCreate() {
        super.onCreate()
        DynamicColors.applyToActivitiesIfAvailable(this)
    }
}

With the custom Application class created, we now need to configure the project to use this class instead of the default Application instance. To do this, edit the AndroidManifest.xml file and add an android:name element referencing the new class:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ebookfrenzy.themedemo">
 
    <application
        android:name=".ThemeDemoApplication"
        android:allowBackup="true"
.
.

Build and run the app and note that the layout is now using a theme that matches the wallpaper color. Place the ThemeDemo app into the background, return to the Wallpaper & styles settings screen and choose a different wallpaper. Bring the ThemeDemo app to the foreground again at which point it will have dynamically adapted to match the new wallpaper.

Summary

In this chapter, we have made use of the Material Theme Builder to design a new theme and explained the steps to integrate the generated theme files into an Android Studio project. Finally, the chapter demonstrated how to implement and use the Material You dynamic colors feature of Android 12.