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.