Core Material 3 Components
Material 3 in Compose
Material 3 (Material You) is the latest version of Google's design system. Compose provides first-class Material 3 components through the material3 artifact. These components handle their own state, accessibility, and theming.
Buttons
@Composable
fun ButtonExamples() {
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
// Filled button (primary action)
Button(onClick = { /* handle click */ }) {
Text("Filled Button")
}
// Outlined button (secondary action)
OutlinedButton(onClick = { /* handle click */ }) {
Text("Outlined Button")
}
// Text button (tertiary action)
TextButton(onClick = { /* handle click */ }) {
Text("Text Button")
}
// Icon button
IconButton(onClick = { /* handle click */ }) {
Icon(
imageVector = Icons.Default.Favorite,
contentDescription = "Favorite"
)
}
// Extended FAB
ExtendedFloatingActionButton(
onClick = { /* handle click */ },
icon = { Icon(Icons.Default.Add, contentDescription = null) },
text = { Text("Add Item") }
)
}
}
Cards
@Composable
fun ProductCard(product: Product) {
Card(
modifier = Modifier.fillMaxWidth(),
onClick = { /* navigate to detail */ }
) {
Column(modifier = Modifier.padding(16.dp)) {
AsyncImage(
model = product.imageUrl,
contentDescription = product.name,
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.clip(RoundedCornerShape(12.dp))
)
Spacer(modifier = Modifier.height(12.dp))
Text(text = product.name, style = MaterialTheme.typography.titleMedium)
Text(text = product.price, style = MaterialTheme.typography.bodyMedium)
}
}
}
Three card variants:
Card()-- filled backgroundOutlinedCard()-- outlined borderElevatedCard()-- elevated with shadow
TopAppBar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ScreenWithTopBar() {
Scaffold(
topBar = {
TopAppBar(
title = { Text("My App") },
navigationIcon = {
IconButton(onClick = { /* back */ }) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
}
},
actions = {
IconButton(onClick = { /* search */ }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
IconButton(onClick = { /* settings */ }) {
Icon(Icons.Default.Settings, contentDescription = "Settings")
}
}
)
}
) { padding ->
// Screen content with padding from Scaffold
Column(modifier = Modifier.padding(padding)) {
Text("Content goes here")
}
}
}
TextFields
@Composable
fun SearchBar() {
var query by remember { mutableStateOf("") }
OutlinedTextField(
value = query,
onValueChange = { query = it },
label = { Text("Search") },
leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
trailingIcon = {
if (query.isNotEmpty()) {
IconButton(onClick = { query = "" }) {
Icon(Icons.Default.Clear, contentDescription = "Clear")
}
}
},
singleLine = true,
modifier = Modifier.fillMaxWidth()
)
}
Material 3 Theming
Color Scheme
Material 3 uses a dynamic color system derived from the user's wallpaper (on Android 12+). You define a color scheme with primary, secondary, tertiary, and surface colors.
// Define custom colors
val md_theme_light_primary = Color(0xFF6750A4)
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
val md_theme_light_secondary = Color(0xFF625B71)
val md_theme_light_surface = Color(0xFFFFFBFE)
private val LightColorScheme = lightColorScheme(
primary = md_theme_light_primary,
onPrimary = md_theme_light_onPrimary,
secondary = md_theme_light_secondary,
surface = md_theme_light_surface
)
private val DarkColorScheme = darkColorScheme(
primary = Color(0xFFD0BCFF),
onPrimary = Color(0xFF381E72),
secondary = Color(0xFFCCC2DC),
surface = Color(0xFF1C1B1F)
)
Typography
val AppTypography = Typography(
displayLarge = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 57.sp,
lineHeight = 64.sp
),
titleLarge = TextStyle(
fontWeight = FontWeight.SemiBold,
fontSize = 22.sp,
lineHeight = 28.sp
),
bodyLarge = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp
)
)
Applying the Theme
@Composable
fun AmazonPrepTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
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 -> DarkColorScheme
else -> LightColorScheme
}
MaterialTheme(
colorScheme = colorScheme,
typography = AppTypography,
content = content
)
}
// Usage in Activity
setContent {
AmazonPrepTheme {
MainScreen()
}
}
Dynamic Color
On Android 12+, dynamicLightColorScheme and dynamicDarkColorScheme extract colors from the user's wallpaper. This gives each user a unique, personalized theme. The when block above falls back to your custom scheme on older devices.
Using Theme Values
Access theme values through MaterialTheme:
@Composable
fun ThemedText() {
Text(
text = "Themed text",
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.titleLarge
)
}
Quiz
1. What does Scaffold provide in Material 3?
2. What is dynamic color in Material 3?
3. Which component replaces the deprecated BottomNavigation in Material 3?
4. How do you access the current color scheme in a composable?
Flashcards
Question
What are the three card variants in Material 3 Compose?
Click to reveal answer
Answer
Card (filled), OutlinedCard (border), and ElevatedCard (shadow). All accept onClick and content lambdas.
Question
What is the purpose of Scaffold in Compose?
Click to reveal answer
Answer
Question
How do you enable dynamic color in a Material 3 theme?
Click to reveal answer
Answer
Use dynamicLightColorScheme(context) or dynamicDarkColorScheme(context) on Android 12+ and fall back to a custom color scheme on older devices.
Question
What is the difference between Button and TextButton?
Click to reveal answer
Answer
Button has a filled background for primary actions. TextButton has no background, used for tertiary or low-emphasis actions.
Revision Notes
Key Takeaways
- 1. Scaffold provides the Material layout structure with proper padding management
- 2. NavigationBar with NavigationBarItem replaces deprecated BottomNavigation
- 3. Dynamic color extracts palette from wallpaper on Android 12+
- 4. Access theme values via MaterialTheme.colorScheme and MaterialTheme.typography
- 5. Use Dialog, BottomSheet, and Snackbar for transient UI elements
Interview Tips
- • Know the difference between Button variants and when to use each
- • Explain how dynamic color works and its fallback behavior
- • Discuss Scaffold padding and why applying it to content is critical
- • Be ready to compare Material 2 vs Material 3 naming changes
Cheat Sheet
Material 3 Cheat Sheet
Core Components:
- Button, OutlinedButton, TextButton -- primary/secondary/tertiary actions
- Card, OutlinedCard, ElevatedCard -- content containers
- TopAppBar -- navigation and actions at the top
- NavigationBar + NavigationBarItem -- bottom navigation
- TextField, OutlinedTextField -- text input
- AlertDialog, ModalBottomSheet -- overlays
Layout:
- Scaffold provides topBar, bottomBar, FAB, content slots
- Always apply Scaffold padding to content
Theming:
- lightColorScheme() / darkColorScheme() for custom colors
- dynamicLightColorScheme() for wallpaper-based colors (API 31+)
- MaterialTheme.colorScheme / .typography / .shapes for access
- Wrap app in MaterialTheme at the root