The appearance of an Android app is intended to conform to a set of guidelines defined by Material Design. Material Design was developed by Google to provide a level of design consistency between different apps, while also allowing app developers to include their own branding in terms of color, typography, and shape choices (a concept referred to as Material theming). In addition to design guidelines, Material Design also includes a set of UI components for use when designing user interface layouts, many of which we have been using throughout this book.
In this chapter, we will provide an overview of how theming works within an Android Studio project and explore how the default design configurations provided for newly created projects can be modified to meet your branding requirements.
Material Design 2 vs Material Design 3
Before beginning, it is important to note that Google is currently transitioning from Material Design 2 to Material Design 3 and that projects created with Android Studio Chipmunk default to Material Design 2 unless you select the Basic Activity (Material3) template when creating a new project. Material Design 3 provides the basis for Material You, a feature introduced in Android 12 that allows an app to automatically adjust theme elements to compliment preferences configured by the user on the device. Dynamic color support provided by Material Design 3, for example, allows the colors used in apps to automatically adapt to complement the user’s wallpaper selection.
Understanding Material Design Theming
We know, of course, that Android app user interfaces are created by assembling components such as layouts, text fields, and buttons. All of these components appear using default colors unless we specifically override a color attribute either in the XML layout resource file or by writing code. These default colors are defined by the project’s theme. The theme consists of a set of color slots (declared in themes.xml files) to which are assigned color values (declared in the colors.xml file). Each UI component is programmed internally to use theme color slots as the default color for specific attributes (such as the foreground and background colors of the Text widget). It follows, therefore, that we can change the application-wide theme of an app simply by changing the colors assigned to specific theme slots. When the app runs, the new default colors will be used as the defaults for all of the widgets when the user interface is rendered.
Material Design 2 Theming
Before exploring Material Design 3, we first need to look at how Material Design 2 is used in an Android Studio project. The theme used by an application project is declared as a property of the application element within the AndroidManifest.xml file, for example:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ebookfrenzy.themedemo"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyDemoApp"> <activity . .
As previously discussed, all of the files associated with the project theme are contained within the colors.xml and themes.xml files located in the res -> values folder as shown in Figure 92-1:
The theme itself is declared in the two themes.xml files located in the themes folder. These resource files declare different color palettes containing Material Theme color slots for use when the device is in light or dark mode. Note that the style name property in each file must match that referenced in the AndroidManifest.xml file:
<resources xmlns:tools="http://schemas.android.com/tools"> <!-- Base application theme. --> <style name="Theme.MyDemoApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> <!-- Primary brand color. --> <item name="colorPrimary">@color/purple_500</item> <item name="colorPrimaryVariant">@color/purple_700</item> <item name="colorOnPrimary">@color/white</item> <!-- Secondary brand color. --> <item name="colorSecondary">@color/teal_200</item> . .
These color slots (also referred to as color attributes) are used by the Material components to set colors when they are rendered on the screen. For example, the colorPrimary color slot is used as the background color for 758
Working with Material Design 3 Theming the Material Button component. The actual colors assigned to the slots are declared in the colors.xml resource file as follows:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="purple_200">#FFBB86FC</color> <color name="purple_500">#FF6200EE</color> <color name="purple_700">#FF3700B3</color> <color name="teal_200">#FF03DAC5</color> <color name="teal_700">#FF018786</color> <color name="black">#FF000000</color> <color name="white">#FFFFFFFF</color> </resources>
The colorPrimary slot, for example, is assigned the color purple_500 which, in turn, is assigned an RGB color value of FF6200EE.
Creating a custom theme simply involves editing these files to use different color settings. These changes will then be used by the Material components as the default colors.
Material Design 3 Theming
Material Design 3 (MD3) still uses colors.xml and themes.xml files but provides a broader range of color slots to be used by the MD3 components. In fact, MD3 provides over 25 color slots for use when customizing an app theme. The color names are also different in that they describe the purpose of the color rather than the color itself. In Material Design 2, for example, we had a color named purple_500:
This, in turn, was used for the colorPrimary theme slot in the light mode themes.xml file:
Suppose that we need to change colorPrimary from purple to red. We could, of course, just assign the RGB value for a shade of red to the purple_500 color declaration. Unfortunately, we now have a red color declaration with a name that suggests it is purple. The only option is to add a new entry to the colors.xml file for the red color and then assign it to the colorPrimary slot in the themes.xml file. This works, but to achieve this we had to edit both the color and theme files. In MD3, color names do not reference the actual color they represent. The colorPrimary slot in an MD3 theme file is instead declared as follows:
This color is then declared in the colors.xml file:
We can now change the RGB color value for this color while leaving the themes.xml files unchanged and without having to create a new color element in the colors.xml file.
In addition, elements within MD3 themes.xml files are based on Base.Theme.Material3.* instead of Theme. MaterialComponents.*. The following, for example, is an excerpt from an MD3 themes.xml file:
<resources> <style name="Theme.MyAppDemo" parent="Base.Theme.Material3.Dark.NoActionBar"> <item name="colorPrimary">@color/md_theme_dark_primary</item> <item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item> <item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item> <item name="colorOnPrimaryContainer">@color/md_theme_dark_onPrimaryContainer</item> <item name="colorSecondary">@color/md_theme_dark_secondary</item> . . </style> <style name="Theme.ThemeDemo" parent="Base.Theme.ThemeDemo" /> </resources>
Color slots in MD3 are grouped as Primary, Secondary, Tertiary, Error, Background, and Surface. These slots are further divided into pairs consisting of a base color and an “on” base color. This generally translates to the background and foreground colors of a Material component.
The particular group used for coloring will differ between widgets. A Material Button widget, for example, will use the colorPrimary base color for the background color and colorOnPrimary for its content (i.e. the text or icon it displays). The FloatingActionButton component, on the other hand, uses colorPrimaryContainer as the background color and colorOnPrimaryContainer for the foreground. The correct group for a specific widget type can usually be identified quickly by changing color settings in the theme files and reviewing the rendering in the layout editor.
The biggest difference between MD2 and MD3 is support for dynamic colors and Material You, both of which will be covered in the next chapter entitled “A Material Design 3 Theming and Dynamic Color Tutorial”. Note that dynamic colors only take effect when enabled on the device by the user within the wallpaper and styles section of the Android Settings app.
Building a Custom Theme
As we have seen so far, the coding work in implementing a theme is relatively simple. The difficult part, however, is often choosing a set of complementary colors to make up the theme. Fortunately, Google has developed a tool that makes it easy to design custom color themes for your apps. This tool is called the Material Theme Builder and is available at:
From within the builder tool, select the Custom tab (marked A in Figure 92-2) and make a color selection for the primary color key (B) by clicking on the color rectangle to display the color selection dialog. Once a color has been selected, the theme panel (C) will change to reflect the recommended colors for all of the MD3 color slots. The generated colors for the Secondary, Tertiary, and Neutral slots can be overridden by clicking on the circles (D) and selecting different colors from the color selection panel:
To incorporate the theme into your design, click on the Export button (E) and select the Android View (XML) option. Once downloaded, the colors.xml and themes.xml files can be used to replace the existing files in your project. Note that the theme name in the two exported themes.xml files will need to be changed to match your project.
Material Design provides guidelines and components that define how Android apps look and appear. Individual branding can be applied to an app by designing themes that specify the colors, fonts, and shapes that should be used when the app is displayed. Google is currently introducing Material Design 3 which replaces Material Design 2 and supports the new features of Material You including dynamic colors. For designing your own themes, Google also provides the Material Theme Builder which eases the task of choosing complementary theme colors. Once this tool has been used to design a theme, the corresponding files can be exported and used within an Android Studio project.