Back to Blog
    Engineering
    10 min read
    April 14, 2026

    Android UI Tutorial: How to Implement and Customize Toast on Android

    Android UI Tutorial: How to Implement and Customize Toast on Android
    Quick answer

    To implement a toast on Android, use the Toast.makeText() method with a context, message, and duration (LENGTH_SHORT or LENGTH_LONG), followed by the .show() call. Toasts provide non-interactive, transient feedback for lightweight events like 'Item added to cart' without interrupting the user's current workflow.

    Android UI Tutorial: How to Implement and Customize Toast on Android

    If you have spent any time building Android apps, you have almost certainly reached for a Toast at some point. Someone taps Save, something uploads in the background, a form field fails validation — and a small message pops up near the bottom of the screen for a couple of seconds before disappearing. No modal. No navigation change. Just quick feedback.

    That simplicity is exactly why Toast remains one of the first UI patterns junior developers learn. It is also why it gets misused so often. Teams treat every confirmation like Toast material, stack multiple messages on top of each other, or wonder why their custom layout stopped working on newer devices.

    This tutorial walks through how to implement and customise toast on Android properly — using modern Kotlin, understanding the platform restrictions Google introduced from Android 11 onwards, and knowing when a Snackbar or inline message is the better call.

    What Toast Actually Does (and What It Does Not)

    A Toast is a transient overlay managed by the system window layer. It shows text or a custom view briefly, then dismisses itself. Users cannot interact with it beyond reading it. They cannot swipe it away in the traditional sense on most devices, though newer Android versions have tightened how custom Toasts behave.

    Toast works well for lightweight, non-critical feedback:

    • Item added to cart
    • Copied to clipboard
    • Network unavailable — retrying
    • Debug or internal status during development

    It is a poor choice for errors that need action, permission prompts, or anything the user must acknowledge before continuing. For those cases, dialogs, Snackbars, or inline validation messages are more appropriate. Getting this distinction right matters more than most teams realise when they are trying to polish Android user experience across a growing product.

    Basic Toast Implementation in Kotlin

    The classic API has not changed much at its core. You create a Toast with a context, message, and duration, then call show().

    Here is a straightforward example inside an Activity or Fragment:

    import android.widget.Toast
    
    fun showSimpleToast() {
        Toast.makeText(
            this,
            "Profile updated",
            Toast.LENGTH_SHORT
        ).show()
    }
    

    Two duration constants are available:

    • Toast.LENGTH_SHORT — roughly 2 seconds
    • Toast.LENGTH_LONG — roughly 3.5 seconds

    Exact timing varies slightly by device and Android version, so do not design flows that depend on precise millisecond control.

    Triggering Toast from a Button Click

    In a typical layout with a Material button, you might wire it like this:

    binding.saveButton.setOnClickListener {
        saveProfile()
        Toast.makeText(this, "Changes saved", Toast.LENGTH_SHORT).show()
    }
    

    Keep the message short. One line, plain language, no jargon. "Changes saved" beats "Your profile has been successfully updated to the server." Users glance at Toasts; they do not study them.

    Context Matters More Than You Think

    One of the most common Toast-related bugs in Android projects is a context leak or a Toast that never appears because it was called from the wrong thread.

    Use an Activity context when theming matters. If you are showing a standard text Toast inside an active screen, this from an Activity or requireContext() from a Fragment is fine.

    Use applicationContext cautiously. Some developers pass applicationContext to avoid leaks when showing Toasts from background callbacks. That can work for simple text Toasts, but it may ignore your Activity theme and cause subtle styling inconsistencies.

    Always show Toast on the main thread. If you are updating UI after a network call or database operation on a background thread,font-weight: 400; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-size-adjust: none; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-variant-emoji: normal; font-stretch: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">, hop back to the main thread first:

    viewModel.saveResult.observe(viewLifecycleOwner) { result ->
        if (result.isSuccess) {
            Toast.makeText(requireContext(), "Saved", Toast.LENGTH_SHORT).show()
        }
    }
    

    With coroutines, wrap it explicitly if needed:

    withContext(Dispatchers.Main) {
        Toast.makeText(context, "Sync complete", Toast.LENGTH_SHORT).show()
    }
    

    Positioning Toast on Screen

    By default, Toast appears near the bottom centre. You can adjust gravity and offset pixels if a bottom message conflicts with your navigation bar or FAB.

    val toast = Toast.makeText(this, "Uploaded", Toast.LENGTH_SHORT)
    toast.setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL, 0, 100)
    toast.show()
    

    Use offsets sparingly. A Toast drifting to odd corners looks unpolished and can overlap status icons or camera cutouts on modern devices. If you find yourself fighting placement repeatedly, that is usually a sign you need a Snackbar anchored to a specific view instead.

    Custom Toast Layouts: What Still Works in 2026

    Custom Toasts — where you inflate an XML layout and pass it via setView() — were once a popular way to add icons, branded colours, or multi-line styled content. Google deprecated custom Toast views for apps targeting API level 30 (Android 11) and above when those Toasts are shown by background apps or use certain window types.

    For foreground Activities, custom views may still appear on some devices, but relying on them is risky. Play Store policy and OEM behaviour vary, and what works on your test phone may fail silently on another.

    Legacy Custom Toast Pattern (Know It, Do Not Depend on It)

    Older codebases often contain something like this:

    val inflater = layoutInflater
    val layout = inflater.inflate(R.layout.custom_toast, null)
    
    val toast = Toast(applicationContext)
    toast.duration = Toast.LENGTH_LONG
    toast.view = layout
    toast.show()
    

    If you inherit this pattern during a refactor, treat it as technical debt. For new features, prefer alternatives below rather than investing in elaborate custom Toast XML.

    Practical Customisation Without Custom Views

    For simple branding, you can sometimes get away with styled text using Spannable strings, though results are limited:

    val message = SpannableString("Payment failed")
    message.setSpan(StyleSpan(Typeface.BOLD), 0, message.length, 0)
    
    Toast.makeText(this, message, Toast.LENGTH_LONG).show()
    

    Honestly, this rarely impresses users. If custom visual treatment matters — icons, rounded containers, action buttons — build a Snackbar or a small inline banner composable instead.

    Snackbar: The Modern Replacement Most Teams Should Use

    Material Components' Snackbar behaves like an upgraded Toast. It supports action buttons, respects CoordinatorLayout behaviour, and fits Material Design expectations out of the box.

    Snackbar.make(binding.root, "Item removed", Snackbar.LENGTH_SHORT)
        .setAction("Undo") {
            undoRemove()
        }
        .show()
    

    Snackbars anchor to a view hierarchy, which solves many of the placement headaches Toast creates in apps with bottom navigation or floating action buttons. They also feel more intentional to users because the action button gives them control.

    When reviewing UX patterns across an app, we often recommend Snackbars for reversible actions and Toasts only for passive confirmations. That single rule clears up a lot of inconsistent feedback behaviour in high-performance Android development projects.

    Toast in Jetpack Compose

    Compose does not ship a native Toast composable because Toast sits outside the Compose UI tree. The integration is still straightforward — call the standard Android Toast API from your Activity context:

    val context = LocalContext.current
    
    Button(onClick = {
        Toast.makeText(context, "Hello from Compose", Toast.LENGTH_SHORT).show()
    }) {
        Text("Show Toast")
    }
    

    For Compose-first apps, many teams skip Toast entirely and use animated snackbars or bottom sheets built with Compose Material 3. That keeps feedback inside the declarative UI layer and makes testing easier.

    Common Mistakes We See in Production Apps

    Toast looks trivial, which is why it accumulates bad habits. These come up repeatedly during code reviews:

    • Showing Toasts from Services without a visible Activity. Background services should use notifications, not Toasts. Users may never see the message.
    • Stacking multiple Toasts. Rapid-fire Toasts queue up and feel chaotic. Debounce repeated events or consolidate messages.
    • Using Toast for critical errors. "Payment declined" should not vanish after two seconds with no way to retry.
    • Hard-coded strings. Always pull copy into strings.xml for localisation. Indian apps often ship in English, Hindi, and regional languages — plan for that early.
    • Showing Toast on every API success. If the UI already reflects the change (a checkmark, updated list item), the Toast is redundant noise.
    • Creating a new Toast helper that never cancels the previous one. Consider a singleton helper that cancels the active Toast before showing the next if your app fires frequent updates.

    A Simple Toast Helper Worth Having

    Centralising Toast logic prevents context mistakes and duplicate strings:

    object AppToast {
        private var currentToast: Toast? = null
    
        fun show(context: Context, @StringRes messageRes: Int, length: Int = Toast.LENGTH_SHORT) {
            currentToast?.cancel()
            currentToast = Toast.makeText(context.applicationContext, messageRes, length)
            currentToast?.show()
        }
    }
    

    Using applicationContext here is acceptable for a global helper showing plain text, but only invoke it when an Activity is in the foreground if you care about the user actually seeing it.

    Accessibility and UX Considerations

    Toasts are easy to miss. Screen readers may not announce them reliably depending on device and TalkBack version. Users with motor difficulties cannot interact with them. Low-vision users may not notice brief bottom overlays.

    If the message conveys important state, mirror it elsewhere:

    • Update visible UI text
    • Announce via accessibility APIs where appropriate
    • Use persistent inline error labels for form validation

    Also respect dark mode and dynamic colour. Default Toast styling follows system theme on many devices, but custom hacks often break in dark mode — another reason to favour Material Snackbars tied to your app theme.

    When Toast Is Still the Right Choice

    Despite the platform moving toward Snackbars and inline feedback, Toast remains appropriate in specific situations:

    • Quick developer debugging during QA builds (remove or gate behind BuildConfig.DEBUG before release)
    • Simple confirmations in utility apps with minimal UI chrome
    • Legacy module maintenance where refactoring to Snackbar is not budgeted yet
    • Passive status updates with no required user action

    The goal is not to eliminate Toast entirely. It is to use it deliberately rather than as a default hammer for every feedback nail.

    Testing Toast Behaviour

    Toasts are annoying to test with Espresso because they render outside the Activity view hierarchy. Teams usually take one of these approaches:

    • Abstract feedback behind an interface and verify the interface was called in unit tests
    • Use UI tests sparingly for Toast, focusing instead on Snackbar text within the hierarchy
    • Replace Toast with a testable event channel in ViewModel-driven architectures

    If test coverage matters for your release pipeline — and it should for anything customer-facing — design feedback as an event the UI layer renders, not a side effect buried inside a repository class.

    Conclusion

    Implementing toast on Android takes about five minutes. Getting it right across an entire app takes more thought. Start with Kotlin's standard Toast.makeText() for simple, passive confirmations. Understand context and threading rules before copying Stack Overflow snippets into background jobs. Treat custom Toast layouts as legacy unless you have a specific compatibility reason to keep them.

    For anything requiring user action, undo, or consistent Material Design styling, reach for Snackbar or Compose-native feedback components instead. Your users may not comment on good feedback patterns, but they absolutely notice when messages flash too quickly, pile up, or disappear before they finish reading.

    Toast is a small UI detail. In a polished Android product, small details are exactly what separate apps that feel reliable from apps that feel rushed.

    By the Numbers

    • Android continues to maintain a dominant global market share, making the mastery of native UI patterns like Toasts essential for reaching the majority of mobile users. (StatCounter Global Stats)
    • The vast ecosystem of Android applications relies heavily on Kotlin and Java, which remain primary languages for mobile development according to developer trends. (GitHub Octoverse Report)

    Toasts are best reserved for lightweight, non-critical feedback; using them for critical errors disrupts the user experience and ignores accessibility standards.

    — Pinakinvox Engineering Team

    Frequently Asked Questions

    Is Toast deprecated in Android?
    No, the Toast class itself is not deprecated. What changed is custom Toast views via setView() for apps targeting API 30 and above, especially from background contexts. Standard text Toasts still work fine for foreground Activities.
    Should I use Toast or Snackbar in new Android apps?
    For most new development, Snackbar is the better default. It supports action buttons, aligns with Material Design, and stays anchored to your layout. Use Toast only for brief, passive messages with no user action required.
    Why is my Toast not showing on some devices?
    Common causes include calling show() from a background thread, using a destroyed Activity context, or attempting a custom Toast layout blocked on newer Android versions. Verify you are on the main thread and that an Activity is visible.
    Can I show Toast from a ViewModel?
    You should not call Toast directly from a ViewModel because it needs a Context and creates architectural coupling. Expose a one-time UI event or message state from the ViewModel and let the Activity or Fragment display the Toast.
    How do I show Toast in Jetpack Compose?
    Obtain the Context via LocalContext.current and call Toast.makeText() inside your click handler or LaunchedEffect. For Compose-first apps, consider a Material 3 SnackbarHost instead to keep feedback within the Compose UI tree.

    Book a strategy call

    From zero-to-one product development to scaling infrastructure. Pinakinvox partners with high-growth teams to solve complex technical challenges.

    Recommended by professionals.

    Everything published here is tested and deployed in live production systems. No theories.

    Looking for a technical partner to lead your digital transformation?

    Our team specializes in high-complexity engineering and custom software architecture. Let's talk about building for the long term.

    Partner with

    aws
    partnernetwork