Site icon Howtodoandroid

Getting started with jetpack compose – Theming

Jetpack Compose implements Material Theming and supports a dark theme by default. You can customize color, typography, and shape theming values to fit your product’s brand, and get access to convenient functions for working with a system of dark themes (like isSystemInDarkTheme, lightColors, and darkColors).

The default MaterialTheme from the documentation looks like this:

MaterialTheme( colors = colors, typography = Typography, shapes = Shapes, content = content )

We can set custom attributes:

Check out the example I have created for jetpack compose material theming:

you can download this example from github.


If you’re new to Compose, I highly recommend going through the following articles:

Getting started with jetpack compose – Basic components

Getting started with jetpack compose – Layouts

Getting started with jetpack compose – Modifiers

Getting started with jetpack compose – ConstraintLayout

Getting started with jetpack compose – Scaffold layout


Let’s see the material theme attributes in detail.

Color

Jetpack Compose uses the Color class from Compose’s graphics package. We have many ways to define a color, but there are two common ways we use it more frequently.

One Way is defining the hex code of the color

val <em>Purple200 </em>= <em>Color</em>(0xFFBB86FC)
Code language: HTML, XML (xml)

The other way is specifying the RGB values to the Color class:

val blue = Color(red = 0f, green = 0f, blue = 1f)

Since ARGB Hex is just a bunch of jargon to describe what the heck “0XFF00bc00” means, let me translate:

Create a file called something like Color.kt (the name does not matter) and fill it with immutable values:

Color.kt

import androidx.compose.ui.graphics.Color val <em>Purple200 </em>= <em>Color</em>(0xFFBB86FC) val <em>Purple500 </em>= <em>Color</em>(0xFF6200EE) val <em>Purple700 </em>= <em>Color</em>(0xFF3700B3) val <em>Teal200 </em>= <em>Color</em>(0xFF03DAC5)
Code language: HTML, XML (xml)

Accessing the Color from the color.kt when required.

<em>Text</em>(text = "Jetpack compose" , color = <em>Purple500</em>)
Code language: HTML, XML (xml)

Colors class

The colors class allows us to define different Material Design Color Systems.

class Colors( primary: Color, primaryVariant: Color, secondary: Color, secondaryVariant: Color, background: Color, surface: Color, error: Color, onPrimary: Color, onSecondary: Color, onBackground: Color, onSurface: Color, onError: Color, isLight: Boolean )
https://material.io/design/color/the-color-system.html#color-theme-creation

There are around 13 attributes in the constructor of Colors. Let’s see what each attribute means.

To make our support for DarkMode and LightMode easier, Jetpack Compose also provides two functions that generate default colors for these modes.

private val <em>DarkColorPalette </em>= <em>darkColors</em>(<br> primary = <em>Purple200</em>,<br> primaryVariant = <em>Purple700</em>,<br> secondary = <em>Teal200</em>,<br> onPrimary = Color.White,<br> onSecondary = Color.Black<br>)<br><br>private val <em>LightColorPalette </em>= <em>lightColors</em>(<br> primary = <em>Purple500</em>,<br> primaryVariant = <em>Purple700</em>,<br> secondary = <em>Teal200</em>,<br> onPrimary = Color.White,<br> onSecondary = Color.Black<br>)
Code language: HTML, XML (xml)
Light and Dark Colors

We have successfully created colors for the Material Theme. Let’s create the Typography.

Typography

The Typograph is a class that helps us to style texts. With the help of the Typograph class, we can customize FontFamily, FontStyle, FontWeight, LetterSpacing, TextDecoration, Color, and many more attributes related to texts.

class Typography( defaultFontFamily: FontFamily = FontFamily.Default, h1: TextStyle, h2: TextStyle, h3: TextStyle, h4: TextStyle, h5: TextStyle, h6: TextStyle, subtitle1: TextStyle, subtitle2: TextStyle, body1: TextStyle, body2: TextStyle, button: TextStyle, caption: TextStyle, overline: TextStyle )
https://material.io/design/typography/the-type-system.html#type-scale

In addition to this, we should configure a Typography object with the following parameters:

We can override the needed font Style like h1, body1, button, etc as below,

Type.kt

val <em>Typography </em>= Typography( body1 = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, fontSize = 16.<em>sp </em>), button = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.W500, fontSize = 14.<em>sp </em>), caption = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, fontSize = 12.<em>sp </em>) )
Code language: HTML, XML (xml)

The example I have created,

@Composable<br>fun TypographyPreview() {<br><br> <em>Column</em>(Modifier.<em>width</em>(400.<em>dp</em>).<em>padding</em>(10.<em>dp</em>)) <strong>{<br></strong><strong> </strong><em>Text</em>(text = "H2 " ,style = MaterialTheme.typography.h2)<br> <em>Spacer</em>(modifier = Modifier.<em>padding</em>(4.<em>dp</em>))<br> <em>Text</em>(text = "Subtitle 1 " ,style = MaterialTheme.typography.subtitle1)<br> <em>Spacer</em>(modifier = Modifier.<em>padding</em>(4.<em>dp</em>))<br> <em>Text</em>(text = "Body 1 " ,style = MaterialTheme.typography.body1)<br> <em>Spacer</em>(modifier = Modifier.<em>padding</em>(4.<em>dp</em>))<br> <em>Text</em>(text = "Button " ,style = MaterialTheme.typography.button)<br> <em>Spacer</em>(modifier = Modifier.<em>padding</em>(4.<em>dp</em>))<br> <em>Text</em>(text = "Caption " ,style = MaterialTheme.typography.caption)<br><br> <strong>}<br></strong><strong><br></strong>}
Code language: HTML, XML (xml)
Typography

Done with the Typography. finally, create the shape.

Shape

Shape

Creating shapes with Jetpack Compose is super easy. Similar to how we created the Typography instance, we also create the instance of Shapes.

Shape.kt

import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Shapes import androidx.compose.ui.unit.dp val <em>Shapes </em>= Shapes( small = <em>RoundedCornerShape</em>(4.<em>dp</em>), medium = <em>RoundedCornerShape</em>(4.<em>dp</em>), large = <em>RoundedCornerShape</em>(0.<em>dp</em>) )
Code language: HTML, XML (xml)

Let’s Create a Material Theme

By using the instances of colorstypography, and shapes above, we can make a material theme that can be used across the application.

@Composable<br>fun JetpackComposeThemingTheme(<br> colors: Colors,<br> content: @Composable() () -> Unit<br>) {<br> <em>MaterialTheme</em>(<br> colors = colors,<br> typography = <em>Typography</em>,<br> shapes = <em>Shapes</em>,<br> content = content<br> )<br>}
Code language: HTML, XML (xml)

CustomComposeTheme is a composable function with two attributes:

isDarkTheme — To set the dark or light color scheme based on checking isSystemInDarkTheme.
content — A composable function where the MaterialTheme is to be used.

class MainActivity : ComponentActivity() {<br> override fun onCreate(savedInstanceState: Bundle?) {<br> super.onCreate(savedInstanceState)<br><br> <em>setContent </em><strong>{<br></strong><strong> </strong><em>MaterialTheme </em><strong>{<br></strong><strong> </strong><em>Column </em><strong>{<br></strong><strong> </strong><em>Text</em>(text = "Jetpack Compose")<br> <strong>}<br></strong><strong> }<br></strong><strong> }<br></strong><strong><br></strong><strong> </strong>}<br>}
Code language: HTML, XML (xml)

Dark theme

Material composable that makes use of a Surface (like Card, TopAppBar, etc.) automatically includes dark theme properties like desaturated colors for accessibility, elevation overlays, and limited color accents. You can also incorporate these in custom scenarios.

isSystemInDarkTheme() is a call that asks any compatible Android device for the user’s preference for a light or dark theme.

It returns a boolean value which we can use in a Ternary (Conditional) Assignment expression such as

colors = if (darkTheme) DarkColorPalette else LightColorPalette.

code to add the dark mode in the theme,

@Composable<br>fun PurpleTheme(<br> darkTheme: Boolean = <em>isSystemInDarkTheme</em>(),<br> content: @Composable() () -> Unit<br>) {<br> val colors = if (darkTheme) <em>DarkColorPalette </em>else <em>LightColorPalette<br></em><em> </em><em>MaterialTheme</em>(<br> colors = colors,<br> typography = <em>Typography</em>,<br> shapes = <em>Shapes</em>,<br> content = content<br> )<br>}
Code language: HTML, XML (xml)

Material Icons

Jetpack Compose also provides a convenient means of using icons listed in the Material Icons tool, including all icon styles—filled, outlined, rounded, two-tone, and sharp. With this artifact, you can use icons directly, without the need to download SVGs and convert them to VectorDrawables in Android Studio.

Add dependency in the module build.gradle

implementation "androidx.compose.material:material-icons-extended:$compose_version"
Code language: JavaScript (javascript)

You can get the icon by,

Icon(Icons.Default.Add) // Default == Filled Icon(Icons.Outlined.Notifications) Icon(Icons.Rounded.ArrowForward) Icon(Icons.TwoTone.Menu) Icon( Icons.Sharp.Edit, tint = MaterialTheme.colors.primary )
Code language: PHP (php)

That’s all about jetpack compose theming.

You can download this example from Github.

Exit mobile version