Jetpack Compose

Oct 11 2022 · Kotlin 1.7.10, Android 13, Android Studio Chipmunk

Part 2: Build Complex UI with Compose

12. Add Themes & Styling to the App

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 11. Build Custom Dialogs Next episode: 13. Reuse UI in Multiple Screens

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Notes: 12. Add Themes & Styling to the App

The student materials have been reviewed and are updated as of September 2022.

Transcript: 12. Add Themes & Styling to the App

Intro

[Slide 1 - Light and Dark mode]

Up until now, your app used just the light mode the system offered, and a light palette of colors. It’s time to change that! Ever since people started using the Dark mode, to offer an easy-on-the-eyes set of colors for apps, there’s been more and more request for system-default dark modes!

[Slide 2 - Light and Dark mode]

And right now, you can enable default dark mode support for Android apps and the system, through the settings menu!

But that’s not all, Jetpack compose has automatic support for dark and light mode palettes of colors out of the box, with a special MaterialTheme composable function.

Let’s see how to implement it! :]

Demo

Start by opening the file named Theme, within the composeUi package.

[Open file]

As you can see, there’s some code already predefined for you here. There are two constructs already built - the light and dark color palettes. These colors and values are taken from a palette built for this app, and represent various states within each UI component.

  • The primary color is used for things like TopBars, input field highlighting, action buttons and similar.

  • primaryVariant is just a “primary dark” color, used to bring out the primary color, and is used for things like the status bar.

  • secondary colors are used as accent colors, for special types of buttons and actions, mostly for Floating action buttons.

  • surface colors are used for cards and backgrounds of certain components.

  • background colors are used for the default background of non-card components, such as the list, or a column, row and so on.

  • onPrimary colors are used for text, and onSecondary colors are best used for icons, actions and content such as the filter option in the toolbar, and the title text of each TopBar.

There are of course more colors you can explore in each palette, but these are the ones that are important for this app! You can also customize these colors to your preference, but make sure the colors are not too different and your apps don’t turn into an entire spectrum of colors! :]

Now let’s define a custom theme for the Librarian project, that will use dark and light colors, depending on the system preferences:

@Composable
fun LibrarianTheme(
  isDarkTheme: Boolean = isSystemInDarkTheme(),
  content: @Composable () -> Unit
) {
  MaterialTheme(
    colors = if (isDarkTheme) DarkColors else LightColors
  ) {
    content()
  }
}

A theme component is just a wrapper for content. You call the MaterialTheme composable function, which has loads of parameters you can pass in, such as colors, typography and shapes - everything that defines you design style.

Then you pass in the appropriate set of colors, based on whether the system is using the dark theme or not. You can check this from any composable function, by calling isSystemInDarkTheme().

Now that you have that function ready, you can proceed to implement it in the entire app.


The idea is to just wrap every root component of the setContent() function, with the LibrarianTheme function.

So we have to go through each file that uses compose, and set this material theme, and then also change the colors that the system is using, with the color palette from the MaterialTheme.

Start off with the ActionButton:

enabledColor: Color = MaterialTheme.colors.primary

contentColor = MaterialTheme.colors.onSecondary

Notice how you’re using the MaterialTheme.colors.primary, instead of the direct primary color, or the contentColor = MaterialTheme.colors.onSecondary instead of the Color.White. This allows you to fully switch out your color palettes, and have the UI update itself accordingly!

This also means you can copy/paste this component in another project, and it should change its colors and appearance to suit that app! That’s just awesome! :]

The MaterialTheme.colors property is available through the theme of your app, so there are some default colors if you don’t set the theme, but you should always try to style your apps to have your personal look and feel! This behavior is available through something called CompositionLocals, which you’ll learn more about later in the course!

Now go through the rest of the UI; and change the colors and code to match the new setup. Because this is quite tedious to do for the entire app, for simplicity, you can just switch to the final project and see the final result.

Let’s see what one of the setContent wrappers looks like, and then switch to the final project. That’s all you need to do to apply an entire theme to your composables. Now let’s switch to the final project, or you can manually update all of your UI code.

Either way, once you’re ready, build & run the app, and you should see noticeably different UI! :]

[Build & Run, explore app]

The app functions the same, but the UI is different, and looks consistent. Now try changing the device to the dark mode, and see what happens.

[Dark mode on]

You can see the entire UI updates itself without having to restart the app, all by supplying the appropriate DarkColors palette to your MaterialTheme. It’s so simple and clean to style your apps using Jetpack compose, and in turn build beautiful applications, that’ll wow your users! :]