Jetpack Compose - Typography
This example demonstrates how to make a Jetpack Compose Custom Font Family in Android
I have downloaded fonts from https://fonts.google.com/, after that, I created a new directory named font under the res directory and copied fonts .ttf files inside it.
Note: You need to declare fonts with their respective font style and font-weight otherwise it can cause a runtime exception.
Type.kt
package com.boltuix.emptystate.ui.theme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import com.boltuix.emptystate.R
val jostFontFamily = FontFamily(
Font(R.font.jost_book, FontWeight.Normal),
Font(R.font.jost_book, FontWeight.Light),
Font(R.font.jost_book, FontWeight.Medium),
Font(R.font.jost_medium, FontWeight.SemiBold),
Font(R.font.jost_medium, FontWeight.Bold),
)
// Set of Material typography styles to start with
val Typography = Typography(
displayLarge = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.Light,
fontSize = 57.sp,
lineHeight = 64.sp,
letterSpacing = 0.sp
),
displayMedium = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.Light,
fontSize = 45.sp,
lineHeight = 52.sp,
letterSpacing = 0.sp
),
displaySmall = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.Normal,
fontSize = 36.sp,
lineHeight = 44.sp,
letterSpacing = 0.sp
),
headlineLarge = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = 32.sp,
lineHeight = 40.sp,
letterSpacing = 0.sp
),
headlineMedium = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = 28.sp,
lineHeight = 36.sp,
letterSpacing = 0.sp
),
headlineSmall = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = 24.sp,
lineHeight = 32.sp,
letterSpacing = 0.sp
),
titleLarge = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
titleMedium = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.15.sp
),
titleSmall = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 14.sp,
lineHeight = 20.sp,
letterSpacing = 0.1.sp
),
bodyLarge = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.15.sp
),
bodyMedium = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.Medium,
fontSize = 14.sp,
lineHeight = 20.sp,
letterSpacing = 0.25.sp
),
bodySmall = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 12.sp,
lineHeight = 16.sp,
letterSpacing = 0.4.sp
),
labelLarge = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = 14.sp,
lineHeight = 20.sp,
letterSpacing = 0.1.sp
),
labelMedium = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = 12.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
),
labelSmall = TextStyle(
fontFamily = jostFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
)
Theme.kt
package io.material.compose.ui.theme
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.ViewCompat
private val LightThemeColors = lightColorScheme(
primary = md_theme_light_primary,
onPrimary = md_theme_light_onPrimary,
primaryContainer = md_theme_light_primaryContainer,
onPrimaryContainer = md_theme_light_onPrimaryContainer,
secondary = md_theme_light_secondary,
onSecondary = md_theme_light_onSecondary,
secondaryContainer = md_theme_light_secondaryContainer,
onSecondaryContainer = md_theme_light_onSecondaryContainer,
tertiary = md_theme_light_tertiary,
onTertiary = md_theme_light_onTertiary,
tertiaryContainer = md_theme_light_tertiaryContainer,
onTertiaryContainer = md_theme_light_onTertiaryContainer,
error = md_theme_light_error,
errorContainer = md_theme_light_errorContainer,
onError = md_theme_light_onError,
onErrorContainer = md_theme_light_onErrorContainer,
background = md_theme_light_background,
onBackground = md_theme_light_onBackground,
surface = md_theme_light_surface,
onSurface = md_theme_light_onSurface,
surfaceVariant = md_theme_light_surfaceVariant,
onSurfaceVariant = md_theme_light_onSurfaceVariant,
outline = md_theme_light_outline,
inverseOnSurface = md_theme_light_inverseOnSurface,
inverseSurface = md_theme_light_inverseSurface,
)
private val DarkThemeColors = darkColorScheme(
primary = md_theme_dark_primary,
onPrimary = md_theme_dark_onPrimary,
primaryContainer = md_theme_dark_primaryContainer,
onPrimaryContainer = md_theme_dark_onPrimaryContainer,
secondary = md_theme_dark_secondary,
onSecondary = md_theme_dark_onSecondary,
secondaryContainer = md_theme_dark_secondaryContainer,
onSecondaryContainer = md_theme_dark_onSecondaryContainer,
tertiary = md_theme_dark_tertiary,
onTertiary = md_theme_dark_onTertiary,
tertiaryContainer = md_theme_dark_tertiaryContainer,
onTertiaryContainer = md_theme_dark_onTertiaryContainer,
error = md_theme_dark_error,
errorContainer = md_theme_dark_errorContainer,
onError = md_theme_dark_onError,
onErrorContainer = md_theme_dark_onErrorContainer,
background = md_theme_dark_background,
onBackground = md_theme_dark_onBackground,
surface = md_theme_dark_surface,
onSurface = md_theme_dark_onSurface,
surfaceVariant = md_theme_dark_surfaceVariant,
onSurfaceVariant = md_theme_dark_onSurfaceVariant,
outline = md_theme_dark_outline,
inverseOnSurface = md_theme_dark_inverseOnSurface,
inverseSurface = md_theme_dark_inverseSurface,
)
@Composable
fun Material3ComposeTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkThemeColors
else -> LightThemeColors
}
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
(view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb()
ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme
}
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
TypographyDemo.kt
package io.material.compose
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import io.material.compose.ui.design.*
import io.material.compose.ui.theme.Purple40
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TextFieldDemo(navController: NavController) {
Scaffold(
topBar = {
CenterAlignedTopAppBar(
title = { Text("Text fields") },
Modifier.background(Purple40),
navigationIcon = {
IconButton(onClick = { /* doSomething() */
navController.navigateUp()
}) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = "Localized description"
)
}
},
/*actions = {
IconButton(onClick = { *//* doSomething() *//* }) {
Icon(
imageVector = Icons.Filled.Favorite,
contentDescription = "Localized description"
)
}
}*/
)
},
content = {
Column(
modifier = Modifier
.padding(20.dp)
.verticalScroll(rememberScrollState())
) {
Text("Simple Text Field Sample",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
SimpleTextFieldSample()
ListDividerPadding()
Text("Simple Outlined Text Field Sample",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
SimpleOutlinedTextFieldSample()
ListDividerPadding()
Text("Text Field With Icons",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
TextFieldWithIcons()
ListDividerPadding()
Text("Text Field With Placeholder",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
TextFieldWithPlaceholder()
ListDividerPadding()
Text("Text Field With Error State",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
TextFieldWithErrorState()
ListDividerPadding()
Text("Text Field With Helper Message",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
TextFieldWithHelperMessage()
ListDividerPadding()
Text("Password Text Field",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
PasswordTextField()
ListDividerPadding()
Text("Text Field Sample",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
TextFieldSample()
ListDividerPadding()
Text("Outlined Text Field Sample",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
OutlinedTextFieldSample()
ListDividerPadding()
Text("Text Field With Hide Keyboard On Ime Action",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
TextFieldWithHideKeyboardOnImeAction()
ListDividerPadding()
Text("Text Area",
Modifier.padding(bottom = 10.dp),
style = MaterialTheme.typography.labelLarge)
TextArea()
ListDividerPadding()
}
}
)
}
..
Add dependency:
implementation 'androidx.compose.material3:material3:1.0.0-alpha11'
..
Comments
Post a Comment