Styling Theme (with Dark Mode) and Material Components in Android Applications

Shivam Dhuria
ProAndroidDev
Published in
4 min readMay 2, 2020

--

This is the Part 2 of the Series on Material Theme. To know how to add material components to your app, Part 1 here.

Use this as starting point for this guide.

Naming Convention

Since there is no way to differentiate between a style or a theme as both a wrapped around in <Style> tag. I’ll follow this naming convention.

StyleType . AppName . SubGroupName* . Variant* (* = optional)

For a name of a toolbar style, use something like

Widget.Zimgur.Toolbar

and for a theme use

Theme.Zimgur.DayNight

If you’d like to learn by implanting this in code, here’s a starting point you can use.

Split Files on basis of Purpose 🔧

Instead of wring all the styles in styles.xml , we will split the file on the basis of purpose. type.xml will contain on typography styles, shape.xml will contain all shape styling and style.xml will contain all widget styling.

Typography ⌨️

Material Design Guidelines recommend that you only use specific styles of text in your application. You can find more about the type system here. By Default, Material theme uses Roboto Font, I’ll inherit from TextAppearance.Zimgur.Headline3 and then override the font and other properties for some.

Under values package, create a new Resource File called type.xml

Define these values

Now implement these as theme attributes in themes.xml file.

If you don’t override these, the default attributes remain these.

Now in item_galley_album.xml

Shapes 🔴 🔶

Create a new resource file called Shape.xml in values.

Components are organised into three categories, based on their relative size. Components linked to their category will inherit the shape values assigned to the category.

Small Components includes Button, Chip, FAB, TextField . All these will inherit from shapeAppearanceSmallComponent attribute in theme which you will later point to these styles.

Similarly , Medium Component include Dialog Boxes and Material Cards while Large Components include Nav Drawer(side and bottom)

Now point the theme attributes to the above set styles

And you’re done. All the components will automatically inherit the shape values assigned to their category.

But, If you noticed, The modal Bottom sheet that comes up when you long press a post, doesn’t have rounded edges. Ideally it should inherit from shapeAppearanceLargeComponent but since we have put a Navigation View inside it, it covers up the otherwise rounded corners.

To fix this , go to styles.xml

Now, set theme attribute navigationViewStyle to the above style.

Note: Bottom Modal Sheet applies a Shape Overlay which has its bottom left and right corners set to 0 dp as can be seen in the image.

Color 🎨

Use the Material Design Palette to generate a color palette. My palette looks something like this.

In the Colors.xml file, list all the colors you will be using throughout the app(Both for light and dark mode).

Now set theme attributes to these values.

I’ll only discuss the attributes that might be a little hard to understand.

Surface colors affect surfaces of components, such as cards, sheets, and menus .

Attributes like “colorOn….” are pretty self explanatory. For example, if you set icon tint color to ColorOnPrimary which is on a surface with Primary Color background, you can be sure the icon will always contrast with the Primary Color in both Light and Dark Mode.

ColorPrimarySurface, now Google came out with this attribute which is composed of ColorPrimary and ColorSurface. The value of this is ColorPrimary in LIGHT mode and ColorSurface is DARK mode. This is important as in dark mode, you should avoid having bright colors (eg ColorPrimary) for large surfaces(Think Modal Sheet etc) but use ColorSurface which should be dark.A lot of widgets have styles buily in which will inherit this style automatically.

I point this style to the Bottom App Bar Style in themes.

Theme 🎢

Right click values>New Resource File. Set File name as themes and add qualifier Night Mode. You should have two themes.xml files now, One for day mode and one for night mode.

I want to add a transition when user switched from Light to Dark mode and vice verse.

Add this to styles.xml

and then set this style to windowAnimationStyle attribute in themes.xml.

Now time to configure the themes.xml(night) file.

Now, Dark mode is successfully set up in your app.Also call recreate() method after you programatically change theme in your app.

Full Screen 📺

To provide a more immersive experience, sometimes you’d want to make your App fullscreen.

Make sure you add some top padding to the recycler, so that the first item in recycler doesn’t get covered by status bar.

And we are done! ✅ ✅ ✅ ✅

You can find the complete code here.

References/Further Reading

Google Material Components Android examples here

Developing themes with Style.

--

--