Expert: features and shipping · Permissions, Material 3 and polish · topic 37 of 50 · 30 min
Material components
Explanation
Why standard components?
Users have learnt how Android apps work from thousands of apps: a bar at the top with the title, tabs at the bottom, a round button for the main action. Using standard Material components means your app feels familiar from the first tap, gets accessibility support for free, and follows the theme automatically.
| Component | Use for | Example |
|---|---|---|
| TopAppBar | Screen title, back arrow, a few actions | "My orders" with a search icon |
| NavigationBar | 3 to 5 top-level sections at the bottom | Home, Search, Orders, Account |
| FloatingActionButton | The single most important action | "New note", "Compose message" |
| Card | A group of related content | A product, a booking |
| AlertDialog | Important decisions or warnings | "Cancel this order?" |
| Snackbar | Short feedback, optional undo | "Item removed. UNDO" |
| ModalBottomSheet | Extra options or details | Sort and filter options |
Most of these components plug into Scaffold slots, which you met in module 6: topBar, bottomBar, floatingActionButton and snackbarHost.
Bottom navigation
@Composable
fun MainBottomBar(current: String, onSelect: (String) -> Unit) {
NavigationBar {
listOf("Home" to Icons.Default.Home, "Orders" to Icons.Default.List, "Account" to Icons.Default.Person)
.forEach { (label, icon) ->
NavigationBarItem(
selected = current == label,
onClick = { onSelect(label) },
icon = { Icon(icon, contentDescription = label) },
label = { Text(label) },
)
}
}
}Dialogs
if (showCancelDialog) {
AlertDialog(
onDismissRequest = { showCancelDialog = false },
title = { Text("Cancel order?") },
text = { Text("Your refund will reach the original payment method in 5-7 days.") },
confirmButton = { TextButton(onClick = { onCancelOrder(); showCancelDialog = false }) { Text("Cancel order") } },
dismissButton = { TextButton(onClick = { showCancelDialog = false }) { Text("Keep order") } },
)
}Snackbars
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(snackbarHost = { SnackbarHost(snackbarHostState) }) { padding ->
Button(onClick = {
scope.launch {
val result = snackbarHostState.showSnackbar("Item removed", actionLabel = "Undo")
if (result == SnackbarResult.ActionPerformed) restoreItem()
}
}, Modifier.padding(padding)) { Text("Remove") }
}Snackbars are better than Toasts for in-app messages: they follow the theme, can carry an action like Undo, and are announced by screen readers. Keep the text short.
Cards, chips (small selectable labels such as "Veg only" filters), switches, checkboxes, sliders and progress indicators complete the everyday set. All of them read colours and shapes from MaterialTheme, so a well-built theme makes every component look right without extra work.
Choosing well
- Only one FAB per screen, for the most common action.
- Use dialogs sparingly; they interrupt. For simple undoable actions, act immediately and offer Undo in a Snackbar.
- Bottom navigation for 3 to 5 sections; more than that belongs in a menu or drawer.
- Bottom sheets are great on phones for filters and choices because they are within thumb reach.
Common mistakes
- Confirming every small action with a dialog. Prefer Undo.
- Vague dialog buttons like "Yes" and "No". Use actions: "Delete", "Keep".
- Several FABs or a FAB for a rare action.
- Icon-only bottom navigation without labels: harder to understand and to use with screen readers.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Material components · 1/6
Standard Material components feel familiar and are accessible from the start.
Prefer a video by a teacher? Find free videos on “material 3 components compose topappbar navigationbar snackbar dialog bottom sheet” on YouTube ↗
In real life: A notes app screen
A notes app uses a TopAppBar with a search action, a LazyColumn of note Cards, a FAB to create a note, and a NavigationBar for Notes, Reminders and Settings. Swiping a note deletes it at once and shows a Snackbar with Undo, so there is no annoying confirmation dialog, yet nothing is lost by mistake.
Scaffold(
topBar = { TopAppBar(title = { Text("Notes") }) },
floatingActionButton = {
FloatingActionButton(onClick = onNewNote) { Icon(Icons.Default.Add, contentDescription = "New note") }
},
snackbarHost = { SnackbarHost(snackbarHostState) },
bottomBar = { MainBottomBar(current = "Notes", onSelect = onTab) },
) { padding ->
NotesList(Modifier.padding(padding))
}Practice (0/3 done)
A user deletes a cart item. What is the friendliest pattern?
How many main sections suit a bottom NavigationBar?
Build a Scaffold screen for an order history page with a TopAppBar, a NavigationBar with three items, a list of order Cards, a "Cancel order" AlertDialog with clear button labels, and a Snackbar that confirms cancellation with an Undo action.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Accessibility and adaptive layoutsPermissions, Material 3 and polish · same module
- Runtime permissionsPermissions, Material 3 and polish · same module
- Planning screens and user flowsFull-Stack Development · Planning an app
- Why React: components and JSXFrontend Web Development · React concepts
- Bloc, Cubit and choosing an approachFlutter and Dart · State management
- Components and props: building the notes listFull-Stack Development · Building the frontend
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
Which component fits "Sort and filter" options on a phone?
Answer: ModalBottomSheet
Bottom sheets suit extra options.
Why is showSnackbar called inside scope.launch?
Answer: It is a suspend function
It suspends until the snackbar is dismissed or actioned.
How is an AlertDialog shown in Compose?
Answer: By including it in the composition while a state flag is true
Declarative: state decides whether it appears.
Which component is for the single most important action on a screen?
Answer: FloatingActionButton
One FAB per screen.
Which function detects whether the system is in dark mode in Compose?Related
Why split a screen into components like NoteCard and NoteForm?Related
Answer: Each small piece can be built, reused and tested on its own
Components keep code tidy. NoteForm, for example, is reused for both the New note and Edit note screens.
A component returns <h1>Menu</h1><p>Today's dishes</p> and gives an error. What is the fix?Related
Answer: Wrap both in one parent, such as a fragment <>...</>
A component must return one parent element. A fragment groups elements without adding an extra div.
What is Scaffold's innerPadding for?Related
Answer: Keeping content clear of the top bar, bottom bar and system bars
Apply it to the content.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Permissions, Material 3 and polish” before its exam: Accessibility and adaptive layouts.
- Module 9 exam: Permissions, Material 3 and polish · 13 questions · 25 min, without help. 4 topics of this module still to finish first.
- Then the next module, Testing Android apps. 50 topics left in the course before the final exam.