Best way to avoid Toast accumulation in Android

You can use the cancel() method of Toast to close a showing Toast.

Use a variable to keep a reference to every Toast as you show it, and simply call cancel() before showing another one.

private Toast mToast = null; // <-- keep this in your Activity or even in a custom Application class

//... show one Toast
if (mToast != null) mToast.cancel();
mToast = Toast.makeText(context, text, duration);
mToast.show();

//... show another Toast
if (mToast != null) mToast.cancel();
mToast = Toast.makeText(context, text, duration);
mToast.show();

// and so on.

You could even wrap that into a small class like so:

public class SingleToast {

    private static Toast mToast;

    public static void show(Context context, String text, int duration) {
        if (mToast != null) mToast.cancel();
        mToast = Toast.makeText(context, text, duration);
        mToast.show();
    }
}

and use it in your code like so:

SingleToast.show(this, "Hello World", Toast.LENGTH_LONG);

//


In Kotlin I use this:

private lateinit var toast: Toast

fun showToast(@StringRes stringId: Int, toastLength: Int = Toast.LENGTH_SHORT)
{
    if (this::toast.isInitialized)
    {
        toast.cancel()
    }

    toast = Toast.makeText(
        requireContext(),
        getString(stringId),
        toastLength
    )

    toast.show()
}

Or when using it in many fragments it is possible to extend the Fragment class, so function showToast doesn't have to be in every fragment.

open class OneToastFragment : Fragment()
{
    private lateinit var toast: Toast

    fun showToast(@StringRes stringId: Int, toastLength: Int = Toast.LENGTH_SHORT)
    {
        if (this::toast.isInitialized)
        {
            toast.cancel()
        }

        toast = Toast.makeText(
            requireContext(),
            getString(stringId),
            toastLength
        )

        toast.show()
    }
}

Also, it can be easy using Toasty library.

Gradle project:

repositories {
    ...
    maven { url "https://jitpack.io" }
}

Gradle module app:

dependencies {
    ...
    implementation 'com.github.GrenderG:Toasty:1.4.2'
}

onCreate in Activity class:

Toasty.Config.getInstance().allowQueue(false).apply(); // set this to avoid toast acumulations

//Test:
int x = 0;
Toasty.info(this, Integer.toString(x++), Toast.LENGTH_SHORT, true).show();
Toasty.info(this, Integer.toString(x++), Toast.LENGTH_SHORT, true).show();
Toasty.info(this, Integer.toString(x++), Toast.LENGTH_SHORT, true).show();

//This will only show a toast with message `2` 

Have only one Toast in this activity.

private Toast toast = null;

Then just check if there's currently a Toast being shown before creating another one.

if (toast == null || !toast.getView().isShown()) {
    if (toast != null) {
        toast.cancel();
    }
    toast = Toast.makeToast("Your text", Toast.LENGTH).show();
}

You can even make that last snippet into a private method showToast(text) to refactor code if you need to display different text messages.

Tags:

Java

Android