Dialogs, Toast & Snackbar

Not every message TrailLog shows the user needs the same weight. Some are just a quick "it worked," some offer a brief chance to undo, and some genuinely need a decision before anything proceeds. Android gives you three different tools for exactly these three cases: Toast, Snackbar, and AlertDialog. This lesson covers all three, with a clear rule for when to reach for each.

Toast: A Brief, Non-Interactive Message

A Toast is a small popup that appears briefly and disappears on its own — the user can't interact with it, and it doesn't require any response. It's the right tool purely for confirming that something happened, with nothing further for the user to do about it:

fun onTrailSaved() {
    Toast.makeText(context, "Trail saved!", Toast.LENGTH_SHORT).show()
}

Toast.makeText() takes a Context, the message, and a duration constant — Toast.LENGTH_SHORT or Toast.LENGTH_LONG — and .show() actually displays it. Nothing about a Toast is anchored to any particular view on screen, which is exactly why it's unsuitable for anything the user might want to act on: there's no button, and no reliable way to attach one.

Snackbar: Informational, With an Optional Action

A Snackbar is Material Design's improved alternative to Toast for most in-app feedback. It appears anchored to the bottom of the screen (properly positioned above a BottomNavigationView or FloatingActionButton when anchored to a CoordinatorLayout or any view within one), and — unlike a Toast — it can include a single action button. Here's TrailLog showing an Undo option right after a trail is deleted, a genuinely common and well-liked pattern in real apps:

private fun deleteTrail(trail: Trail, position: Int) {
    val removedTrail = trail
    trailAdapter.removeAt(position)

    Snackbar.make(binding.root, "Trail deleted", Snackbar.LENGTH_LONG)
        .setAction("Undo") {
            trailAdapter.restoreAt(position, removedTrail)
        }
        .show()
}

Snackbar.make(binding.root, ...) anchors the Snackbar to the given view — usually the screen's root layout — so Android can position it correctly above any bottom bars or floating buttons already on screen. .setAction("Undo") { ... } attaches the button and the lambda that runs if the user taps it; if they don't tap anything before LENGTH_LONG elapses, the trail simply stays deleted. This is exactly the shape of feedback that suits an optional, reversible action — informational, but with a graceful way back.

AlertDialog: When a Decision Is Required

An AlertDialog is a modal dialog: it blocks interaction with the rest of the screen until the user responds. Reach for it only when the app genuinely can't proceed without an answer — for TrailLog, that's confirming a permanent delete, where an Undo Snackbar wouldn't be appropriate because the action can't be quietly reversed. Use MaterialAlertDialogBuilder specifically — the Material-themed version — rather than the plain AlertDialog.Builder, so the dialog matches the rest of TrailLog's Material styling:

private fun confirmPermanentDelete(trail: Trail) {
    MaterialAlertDialogBuilder(requireContext())
        .setTitle("Delete trail?")
        .setMessage("This will permanently remove \"${trail.name}\". This cannot be undone.")
        .setPositiveButton("Delete") { _, _ ->
            viewModel.permanentlyDelete(trail)
        }
        .setNegativeButton("Cancel", null)
        .show()
}

The dialog stays on screen until the user taps either button — there's no dismissing it by accident, and no default action taken silently. Passing null as the listener for setNegativeButton() is a common, valid pattern: "Cancel" only needs to close the dialog, which happens automatically, so no extra code is needed for that button.

Note: These snippets are correct, real Kotlin/Android code, but this website's own project doesn't run a live Android Studio build, so nothing here executes on the page itself.

Choosing the Right One

ToolUse When
ToastPurely informational — the user doesn't need to act on it, and there's nothing to undo.
SnackbarInformational, but with an optional action — most commonly an Undo — that the user can ignore and it quietly goes away.
AlertDialogThe app genuinely needs the user's decision before it can safely proceed, especially before an irreversible action.

BottomSheetDialogFragment: A More Substantial Alternative

When a decision needs more room than a simple two-button dialog — say, letting the user pick a sort order for the trail list, or choose between several export formats — a BottomSheetDialogFragment is often a better fit than either an AlertDialog or navigating to an entirely new screen. It slides up from the bottom of the screen as its own Fragment, showing a larger set of options or even a short form, while the screen underneath stays visible and the user never technically leaves the current screen. It's a heavier tool than a Snackbar or a plain dialog, reserved for exactly the cases where those two feel too small.

Up next: Custom Views covers building your own view class from scratch — useful the moment TrailLog needs a widget that none of the built-in views quite provide.