In Jetpack Compose, typography plays a pivotal role in defining the look and feel of your application. MaterialTheme provides a structured and customizable way to manage your app’s fonts, styles, and overall text appearance. Understanding how to leverage MaterialTheme.typography is essential for creating visually appealing and consistent UIs.
What is MaterialTheme Typography?
MaterialTheme.typography is a core component of the Material Design system in Jetpack Compose, offering a predefined set of text styles. These styles include h1 to h6 (for headings), body1, body2 (for main text), button, caption, and more. Each style provides a set of attributes such as font family, font weight, font size, and letter spacing. By utilizing these predefined styles, you can maintain consistency and ensure a polished look across your app.
Why Use MaterialTheme Typography?
- Consistency: Ensures a consistent typographic style throughout your application.
- Customization: Allows you to easily customize the typography to match your brand.
- Theming: Supports dynamic theming for different modes (e.g., light and dark).
- Readability: Promotes better readability and user experience by utilizing established text styles.
How to Implement MaterialTheme Typography in Jetpack Compose
To effectively implement MaterialTheme.typography, follow these steps:
Step 1: Understand the Default Typography Styles
Material Design provides a set of default typography styles which include:
displayLargedisplayMediumdisplaySmallheadlineLargeheadlineMediumheadlineSmalltitleLargetitleMediumtitleSmallbodyLargebodyMediumbodySmalllabelLargelabelMediumlabelSmall
Step 2: Applying Typography Styles to Text
You can apply these styles directly to your Text composables using the style parameter:
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
@Composable
fun TypographyExample() {
Text(
text = "This is a headline",
style = MaterialTheme.typography.headlineLarge
)
Text(
text = "This is body text",
style = MaterialTheme.typography.bodyMedium
)
Text(
text = "This is a button",
style = MaterialTheme.typography.labelLarge
)
}
@Preview(showBackground = true)
@Composable
fun TypographyExamplePreview() {
TypographyExample()
}
In this example:
- The
headlineLargestyle is applied to the firstTextcomposable, rendering it as a large headline. - The
bodyMediumstyle is applied to the secondTextcomposable, rendering it as the standard body text. - The
labelLargestyle is applied to the thirdTextcomposable, rendering it as a large label, suitable for buttons.
Step 3: Customizing Typography
To customize the typography, you can create a new Typography object with your desired font families, weights, and sizes. You need to also make sure to import the font files you intend to use.
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import androidx.compose.ui.text.font.Font
import com.example.jetpackcompose.R // Replace with your actual resource package
import androidx.compose.runtime.Composable
// Define custom font families
val customFontFamily = FontFamily(
Font(R.font.raleway_regular, FontWeight.Normal), // Replace with your font resource
Font(R.font.raleway_bold, FontWeight.Bold) // Replace with your font resource
)
// Create a custom Typography object
val CustomTypography = Typography(
headlineLarge = TextStyle(
fontFamily = customFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 32.sp
),
bodyMedium = TextStyle(
fontFamily = customFontFamily,
fontWeight = FontWeight.Normal,
fontSize = 16.sp
),
labelLarge = TextStyle(
fontFamily = customFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 14.sp
)
)
@Preview(showBackground = true)
@Composable
fun CustomTypographyExample() {
// Applying the custom Typography
androidx.compose.material3.MaterialTheme(typography = CustomTypography) {
Text(
text = "This is a custom headline",
style = MaterialTheme.typography.headlineLarge
)
Text(
text = "This is custom body text",
style = MaterialTheme.typography.bodyMedium
)
Text(
text = "This is a custom button",
style = MaterialTheme.typography.labelLarge
)
}
}
In this code:
- A custom font family,
customFontFamily, is created using fonts loaded from resources. Make sure that the font files are included into the “`res/font“` directory. - A
Typographyobject namedCustomTypographyis created, specifying the font family, weight, and size for various text styles. - These custom styles are then applied within the
MaterialThemeto ensure they are used consistently throughout your composable.
Step 4: Theming Typography
To support different themes, such as light and dark modes, you can create separate typography configurations for each mode. Use isSystemInDarkTheme() to determine the current theme and apply the corresponding typography.
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.Typography
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
@Composable
fun ThemedTypography() {
val typography = if (isSystemInDarkTheme()) {
// Define dark theme typography
Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Serif,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
color = androidx.compose.ui.graphics.Color.White
)
)
} else {
// Define light theme typography
Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Serif,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
color = androidx.compose.ui.graphics.Color.Black
)
)
}
MaterialTheme(typography = typography) {
Text(
text = "This text changes color based on the theme",
style = MaterialTheme.typography.bodyLarge
)
}
}
@Preview(showBackground = true)
@Composable
fun ThemedTypographyPreview() {
ThemedTypography()
}
Advanced Typography Customization
Using Custom Fonts
You can include custom fonts in your project and use them in your typography. First add font resources directory in “`res“` folder
Implementing Dynamic Type
Dynamic type allows users to adjust the text size in the settings and your application should respond to this. Use LocalDensity.current.fontScale to adjust the font sizes accordingly.
import androidx.compose.material3.Text
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.sp
@Composable
fun DynamicTypeExample() {
val fontScale = LocalDensity.current.fontScale
val dynamicStyle = MaterialTheme.typography.bodyLarge.copy(
fontSize = MaterialTheme.typography.bodyLarge.fontSize * fontScale
)
Text(
text = "This is body text that scales with dynamic type settings",
style = dynamicStyle
)
}
@Preview(showBackground = true)
@Composable
fun DynamicTypeExamplePreview() {
DynamicTypeExample()
}
Conclusion
Effectively using MaterialTheme.typography in Jetpack Compose is crucial for creating a visually appealing, consistent, and accessible user interface. By customizing and applying typography styles, you can enhance your app’s readability, reinforce your brand identity, and ensure a better user experience. Properly implementing typography also allows for better theming and accessibility support, leading to a polished and professional application.