In today’s tutorial, we will learn about Typography in MaterialTheme in the Kotlin Compose Multiplatform KMP Android and iOS application. We will discuss typography usage, implementation, and benefits.
Typography in KMP MaterialTheme Reusable Text Styles Guide
We can define custom reusable text styles using typography in the Root widget of MaterialTheme, which can then be used unlimited times in our application. This will remove code redundancy in our app. We can define all types of Text styles before starting app design from Figma. This will eventually lead to a faster development cycle.
Already exist ready-to-use typography in MaterialTheme:
1. h1: heading 1
1 2 3 4 5 6 |
h1: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Light, fontSize = 96.sp, lineHeight = 112.sp, letterSpacing = (-1.5).sp ), |
2. h2: heading 2
1 2 3 4 5 6 |
h2: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Light, fontSize = 60.sp, lineHeight = 72.sp, letterSpacing = (-0.5).sp ), |
3. h3: heading 3
1 2 3 4 5 6 |
h3: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Normal, fontSize = 48.sp, lineHeight = 56.sp, letterSpacing = 0.sp ), |
4. h4: heading 4
1 2 3 4 5 6 |
h4: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Normal, fontSize = 34.sp, lineHeight = 36.sp, letterSpacing = 0.25.sp ), |
5. h5: heading 5
1 2 3 4 5 6 |
h5: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Normal, fontSize = 24.sp, lineHeight = 24.sp, letterSpacing = 0.sp ), |
6. h6: heading 6
1 2 3 4 5 6 |
h6: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Medium, fontSize = 20.sp, lineHeight = 24.sp, letterSpacing = 0.15.sp ), |
7. subtitle 1: As large-size paragraph text.
1 2 3 4 5 6 |
subtitle1: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Normal, fontSize = 16.sp, lineHeight = 24.sp, letterSpacing = 0.15.sp ), |
8. subtitle 2: Small subtitle paragraph text.
1 2 3 4 5 6 |
subtitle2: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 24.sp, letterSpacing = 0.1.sp ), |
9. body 1: Normally used body text size.
1 2 3 4 5 6 |
body1: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Normal, fontSize = 16.sp, lineHeight = 24.sp, letterSpacing = 0.5.sp ), |
10. body 2: Small body text size.
1 2 3 4 5 6 |
body2: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Normal, fontSize = 14.sp, lineHeight = 20.sp, letterSpacing = 0.25.sp ), |
11. button: Standard button text style.
1 2 3 4 5 6 |
button: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 16.sp, letterSpacing = 1.25.sp ), |
12. caption: For caption text style.
1 2 3 4 5 6 |
caption: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Normal, fontSize = 12.sp, lineHeight = 16.sp, letterSpacing = 0.4.sp ), |
13. overline: Samll text with line height set.
1 2 3 4 5 6 |
overline: TextStyle = DefaultTextStyle.copy( fontWeight = FontWeight.Normal, fontSize = 10.sp, lineHeight = 16.sp, letterSpacing = 1.5.sp ) |
As of now, there are 13 inbuilt custom style sheets available in KMP for text widgets.
How to define custom typography in KMP compose multiplatform?
You cannot create a new Typography property in KMP but override the existing one. In KMP Compose Multiplatform they have already defined all the text styles that we might use in an application. We can override any typography as per our usage.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Custom Typography val AppTypography = Typography( // Overriding Existing h1 Typography h1 = TextStyle( fontFamily = FontFamily.Serif, fontWeight = FontWeight.Bold, fontSize = 36.sp ), // Overriding Existing h1 Typography body1 = TextStyle( fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Normal, fontSize = 24.sp ) ) |
Complete source code for App.kt file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp // Custom Typography val AppTypography = Typography( // Overriding Existing h1 Typography h1 = TextStyle( fontFamily = FontFamily.Serif, fontWeight = FontWeight.Bold, fontSize = 36.sp ), // Overriding Existing h1 Typography body1 = TextStyle( fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Normal, fontSize = 24.sp ) ) @Composable fun App() { MaterialTheme( typography = AppTypography ) { Surface( modifier = Modifier.fillMaxSize(), ) { HomeScreen() } } } @Composable fun HomeScreen() { Column( modifier = Modifier .fillMaxSize() .padding(16.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "Sample Text 1", textAlign = TextAlign.Center, // Calling Override h1 Typography. style = MaterialTheme.typography.h1 ) Spacer(modifier = Modifier.height(16.dp)) Text( text = "Sample Text 2", textAlign = TextAlign.Center, // Calling Override body 1 Typography. style = MaterialTheme.typography.body1 ) Spacer(modifier = Modifier.height(16.dp)) Text( text = "Sample Text 3", textAlign = TextAlign.Center, // Calling existing Typography. style = MaterialTheme.typography.h6 ) Spacer(modifier = Modifier.height(16.dp)) Text( text = "Sample Text 4", textAlign = TextAlign.Center, // Calling existing Typography. style = MaterialTheme.typography.subtitle1 ) } } |
Screenshot in Android:
Screenshot in iOS device: