Dialogs, Toast & Snackbar
Not every message deserves the same amount of attention. A quick "saved" confirmation, a "recipe deleted, want it back?" prompt, and "are you sure you want to permanently delete this?" are three very different levels of interruption. Android gives each one its own widget — Toast, Snackbar, and AlertDialog — and picking the right one is mostly about matching that level of interruption to how important the message actually is.
Toast: A Brief, Fire-and-Forget Message
A Toast is a small popup that appears briefly and disappears on its own. It can't be tapped, dismissed, or interacted with in any way — it's purely informational, for messages the user doesn't need to act on:
// After saving a new recipe
Toast.makeText(this, "Recipe saved!", Toast.LENGTH_SHORT).show();
Snackbar: Informational, With an Optional Action
Snackbar is Material Design's answer to the same problem, with two upgrades over Toast: it's anchored to the bottom of the current screen (so it's clearly tied to what the user just did), and it can carry a single action button. RecipeBox uses this for undoing a deleted recipe:
// RecipeListActivity.java — after the user swipes a recipe away
private void deleteRecipe(final Recipe recipe, final int position) {
viewModel.delete(recipe);
adapter.notifyItemRemoved(position);
Snackbar.make(recyclerView, "Recipe deleted", Snackbar.LENGTH_LONG)
.setAction("UNDO", v -> {
viewModel.insert(recipe);
adapter.notifyItemInserted(position);
})
.show();
}
- Snackbar.make() needs a View from the current layout — it uses that View's parent to find where to attach itself.
- The recipe is deleted from the ViewModel/database immediately, but the Snackbar's "UNDO" action re-inserts it, giving the user a short window to reverse the change without a confirmation dialog getting in their way first.
AlertDialog: When a Decision Is Actually Required
An AlertDialog (or its Material-styled cousin, MaterialAlertDialogBuilder) blocks the rest of the screen until the user responds. Reach for it only when the app genuinely cannot proceed without an answer — like confirming a permanent, unrecoverable delete:
// RecipeListActivity.java — confirming a permanent delete
private void confirmPermanentDelete(final Recipe recipe) {
new MaterialAlertDialogBuilder(this)
.setTitle("Delete recipe?")
.setMessage("\"" + recipe.getTitle() + "\" will be permanently removed. This cannot be undone.")
.setPositiveButton("Delete", (dialog, which) -> viewModel.delete(recipe))
.setNegativeButton("Cancel", null)
.show();
}
Which One to Use: A Quick Reference
| Widget | Use It When |
|---|---|
| Toast | Purely informational — nothing for the user to do, and no harm if they miss it. |
| Snackbar | Informational, but worth offering a quick undo or optional follow-up action. |
| AlertDialog | The app genuinely needs the user's decision before it can safely continue. |
DialogFragment: Surviving Configuration Changes
Showing an AlertDialog directly from an Activity, as above, works for a quick example, but has a real gotcha: if the device rotates while the dialog is open, the dialog is simply gone — it isn't automatically recreated with the new configuration. The recommended fix is to wrap the dialog inside a DialogFragment, which the FragmentManager tracks and restores automatically across rotation, exactly like any other Fragment.
BottomSheetDialogFragment: More Options, More Room
When a decision involves more than two or three choices, a compact AlertDialog starts to feel cramped. BottomSheetDialogFragment slides a larger panel up from the bottom of the screen instead — a good fit for something like RecipeBox's "sort by" options (name, prep time, category) or a longer list of category filters, where a full-width, taller surface reads more naturally than a small centered box.