Related
My use-case is to set background for a view inside RemoteView layout.
remoteViews.setInt(R.id.infoRightTitle, "setBackgroundResource", R.drawable.icon)
remoteViews.setColorStateList(R.id.infoRightTitle, "setBackgroundTintList", ContextCompat.getColorStateList(appContext,R.color.red))
But i was surprised to find that setColorStateList was not available and shows a compilation error.
Unresolved reference: setColorStateList
RemoteViews.java
/**
* Call a method taking one int on a view in the layout for this RemoteViews.
*
* #param viewId The id of the view on which to call the method.
* #param methodName The name of the method to call.
* #param value The value to pass to the method.
*/
public void setInt(int viewId, String methodName, int value) {
addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INT, value));
}
/**
* Call a method taking one ColorStateList on a view in the layout for this RemoteViews.
*
* #param viewId The id of the view on which to call the method.
* #param methodName The name of the method to call.
* #param value The value to pass to the method.
*
* #hide
*/
public void setColorStateList(int viewId, String methodName, ColorStateList value) {
addAction(new ReflectionAction(viewId, methodName, ReflectionAction.COLOR_STATE_LIST,
value));
}
I can see an annotation #hide in the code but no other comments while the method is public.
The code i have shared is simplified version to give a gist of the issue.
Need help to find the solution to this problem ?
As of API 31, setColorStateList is supported on RemoteViews.
In my class MainActivity I created a string:
String s = "Mystring";
And I want to do something like below:
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
Is it possible? If yes, how can I do it?
The documentation of Toast.makeText():
/**
* Make a standard toast that just contains a text view.
*
* #param context The context to use. Usually your Application or Activity object.
* #param text The text to show. Can be formatted text.
* #param duration How long to display the message. Either LENGTH_SHORT or LENGTH_LONG.
*/
public static Toast makeText (Context context, CharSequence text, int duration){ ... }
Notice the use of makeTEXT, not makeTOAST.
You mentioned you're working in an AsyncTask. It is not possible to create toasts from a non-UI thread. Make sure you're displaying your Toast either in onPreExecute, in onPostExecute, or in onProgressUpdate.
If you are using it inside an AsyncTask then write your code in onPostexecute() as you can't access it from doInBackground() since it's Non-UI thread.
Toast.makeText(YourActivityName.this, s, Toast.LENGTH_SHORT).show()
Ya that should work, wht is the problem you getting actually?
Try below code:
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
String s="haha";
Context context = getApplicationContext();
CharSequence text = s;
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration).show();
//you are correct. just use charSequence equal to the string. it should work. works for me.
I have read about this kind of problem here but the answers don't seem to be working.
I show a Toast when user clicks a button. When the user continously clicks the button the toast keeps on being displayed again and again even when the user exits the activity.
The length of the toast is short. Length of the toast cannot be changed as the text is long.
This is what i have tried as of now:
Toast toast;
toast=Toast.makeText(getApplicationContext(),"text",Toast.LENGTH_SHORT);
if(toast.getView().isShown()==false){
toast.show();
}
This did not work.
I tried :
if(toast.getView().isShown()==true){
toast.cancel();
}
in the onStop(). For some reason the cancel method never works.
If i put the .cancel() before i show the app... then there would be another null check for that. But after doing that also it did not work. I can show a dialog box instead of a toast but that would not be a solution.
Is there any way to check whether a toast is being displayed or not?
For reference
Toast Message in Android
How to avoid a Toast if there's one Toast already being shown
How to prevent Multiple Toast Overlaps
Cancelling an already open toast in Android
The trick is to keep track of the last Toast that was shown, and to cancel that one.
What I have done is to create a Toast wrapper, that contains a static reference to the last Toast displayed.
When I need to show a new one, I first cancel the static reference, before showing the new one (and saving it in the static).
Here's full code of the Boast wrapper I made - it mimics enough of the Toast methods for me to use it. By default the Boast will cancel the previous one, so you don't build up a queue of Toasts waiting to be displayed.
This code can be found in my Github gist:
mobiRic/Boast
If you just want to know how to cancel the notifications when exiting your app, you will find lots of help in there. If you have improvements or suggestions, please feel free to fork it and get in touch. This is a very old answer, but code has been stable in production on a few apps for some time.
BTW - this should be a direct drop-in replacement for Toast in most use cases.
package mobi.glowworm.lib.ui.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.Nullable;
import android.widget.Toast;
import java.lang.ref.WeakReference;
/**
* {#link Toast} decorator allowing for easy cancellation of notifications. Use this class if you
* want subsequent Toast notifications to overwrite current ones. </p>
* <p/>
* By default, a current {#link Boast} notification will be cancelled by a subsequent notification.
* This default behaviour can be changed by calling certain methods like {#link #show(boolean)}.
*/
public class Boast {
/**
* Keeps track of certain Boast notifications that may need to be cancelled. This functionality
* is only offered by some of the methods in this class.
* <p>
* Uses a {#link WeakReference} to avoid leaking the activity context used to show the original {#link Toast}.
*/
#Nullable
private volatile static WeakReference<Boast> weakBoast = null;
#Nullable
private static Boast getGlobalBoast() {
if (weakBoast == null) {
return null;
}
return weakBoast.get();
}
private static void setGlobalBoast(#Nullable Boast globalBoast) {
Boast.weakBoast = new WeakReference<>(globalBoast);
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Internal reference to the {#link Toast} object that will be displayed.
*/
private Toast internalToast;
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Private constructor creates a new {#link Boast} from a given {#link Toast}.
*
* #throws NullPointerException if the parameter is <code>null</code>.
*/
private Boast(Toast toast) {
// null check
if (toast == null) {
throw new NullPointerException("Boast.Boast(Toast) requires a non-null parameter.");
}
internalToast = toast;
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Make a standard {#link Boast} that just contains a text view.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, CharSequence text, int duration) {
return new Boast(Toast.makeText(context, text, duration));
}
/**
* Make a standard {#link Boast} that just contains a text view with the text from a resource.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
* #throws Resources.NotFoundException if the resource can't be found.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, int resId, int duration)
throws Resources.NotFoundException {
return new Boast(Toast.makeText(context, resId, duration));
}
/**
* Make a standard {#link Boast} that just contains a text view. Duration defaults to
* {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, CharSequence text) {
return new Boast(Toast.makeText(context, text, Toast.LENGTH_SHORT));
}
/**
* Make a standard {#link Boast} that just contains a text view with the text from a resource.
* Duration defaults to {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #throws Resources.NotFoundException if the resource can't be found.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, int resId) throws Resources.NotFoundException {
return new Boast(Toast.makeText(context, resId, Toast.LENGTH_SHORT));
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Show a standard {#link Boast} that just contains a text view.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
*/
public static void showText(Context context, CharSequence text, int duration) {
Boast.makeText(context, text, duration).show();
}
/**
* Show a standard {#link Boast} that just contains a text view with the text from a resource.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
* #throws Resources.NotFoundException if the resource can't be found.
*/
public static void showText(Context context, int resId, int duration)
throws Resources.NotFoundException {
Boast.makeText(context, resId, duration).show();
}
/**
* Show a standard {#link Boast} that just contains a text view. Duration defaults to
* {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
*/
public static void showText(Context context, CharSequence text) {
Boast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
/**
* Show a standard {#link Boast} that just contains a text view with the text from a resource.
* Duration defaults to {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #throws Resources.NotFoundException if the resource can't be found.
*/
public static void showText(Context context, int resId) throws Resources.NotFoundException {
Boast.makeText(context, resId, Toast.LENGTH_SHORT).show();
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Close the view if it's showing, or don't show it if it isn't showing yet. You do not normally
* have to call this. Normally view will disappear on its own after the appropriate duration.
*/
public void cancel() {
internalToast.cancel();
}
/**
* Show the view for the specified duration. By default, this method cancels any current
* notification to immediately display the new one. For conventional {#link Toast#show()}
* queueing behaviour, use method {#link #show(boolean)}.
*
* #see #show(boolean)
*/
public void show() {
show(true);
}
/**
* Show the view for the specified duration. This method can be used to cancel the current
* notification, or to queue up notifications.
*
* #param cancelCurrent <code>true</code> to cancel any current notification and replace it with this new
* one
* #see #show()
*/
public void show(boolean cancelCurrent) {
// cancel current
if (cancelCurrent) {
final Boast cachedGlobalBoast = getGlobalBoast();
if ((cachedGlobalBoast != null)) {
cachedGlobalBoast.cancel();
}
}
// save an instance of this current notification
setGlobalBoast(this);
internalToast.show();
}
}
Instead of cancelling the toast. change the text. For Example
Toast t;
t = Toast.makeText(this, "hi", 3000);
t.show();
when you need a different toast then use
t.setText("bye");
t.show();
And If you want to dismiss the toast simply call t.cancel()
You can cancel individual Toasts by calling cancel() on the Toast object. AFAIK, there is no way for you to cancel all outstanding Toasts, though.
Try keeping the timestamp of the last toast, and don't allow any new toasts until a timeout period has elapsed.
Something like:
private static final long TOAST_TIMEOUT_MS = 2000; // tweak this constant
private static long lastToastTime = 0;
public void onButtonClicked() {
long now = System.currentTimeMillis();
if (lastToastTime + TOAST_TIMEOUT_MS < now) {
Toast.makeText(...).show();
lastToastTime = now;
}
}
I wouldn't worry about a single toast sticking around for a second after the user exits the app -- this is a pretty standard behavior.
I've been using a common "myToast" which I use "myToast.cancel() prior to issuing a new toast. For Android v2.3 and older, this works great. When a new toast needs to be sent, the old one, if still on-screen, is canceled (and disappears immediately) to be replaced with the new toast. This avoids stacking up a bunch of toasts if the user presses a key multiple times that needs the alert (and other conditions). My actual case is one toast appears when a wrong key is pressed, and another appears if the Clear key is not pressed.
For Android 4.0 and 4.1, issuing a myToast.cancel() before the next toast kills both the current and the next toast. The current cancel() API does indicate it cancels the current AND the next toast (which seems rather stupid). Why cancel a toast you want to put up?
Any ideas on making cancel work consistently across Android versions (and the way it works in v2.3 and older)?
I'll try some inelegant dual toast system with tracking for which toast is in use, but it seems such a pain work around this bad behavior in 4.x to get what works perfectly and logically in older Android versions.
Ok, I solved it, but it's not nearly as clean as I would have liked. I implemented a dual toast approach, where it alternates between two toasts. First we define the toasts for the activity prior to the OnCreate:
Toast toast0;
Toast toast1;
private static boolean lastToast0 = true;
In the OnCreate:
toast0 = new Toast(getApplicationContext());
toast0.cancel();
toast1 = new Toast(getApplicationContext());
toast1.cancel();
And finally, when I need to display the toast and cancel the prior toast at the same time I use something similar to:
if (lastToast0) {
toast0.cancel();
toast1.setDuration(Toast.LENGTH_LONG);
toast1.setText("new message");
toast1.show();
lastToast0 = false;
} else {
toast1.cancel();
toast0.setDuration(Toast.LENGTH_LONG);
toast0.setText("new message");
toast0.show();
lastToast0 = true;
}
If you need to just cancel an existing toast (before it times out) use:
toast0.cancel();
toast1.cancel();
Tested on Nexus 7 (4.1), Emulator 4.0, and several devices with Android 2.2, 2.3.
Instead of calling cancel(). Try resetting the text and call show(). This should cancel the last toast by itself
myToast.setText("wrong key")
myToast.show();
If you keep using the same myToast instead of creating one every time I guess they won't stack up.
Did nandeesh's solution not work for you?
His solution would be cleaner than using two different toasts.
For example, (expanding on his/her answer) prior to onCreate we'd declare the toast:
private Toast myToast;
and in onCreate we'd have to initialize it using makeToast (otherwise we'd get an error):
myToast = Toast.makeText(getApplicationContext(), null, Toast.LENGTH_SHORT);
and whenever we want a toast to be shown we'd simply call:
myToast.setText("some text");
myToast.show();
and this would replace the previous toast properly.
Here is my answer copied from another similar question here:
Android cancel Toast when exiting the app and when toast is being shown
The Boast class accomplishes exactly what you need.
The trick is to keep track of the last Toast that was shown, and to cancel that one.
What I have done is to create a Toast wrapper, that contains a static reference to the last Toast displayed.
When I need to show a new one, I first cancel the static reference, before showing the new one (and saving it in the static).
Here's full code of the Boast wrapper I made - it mimics enough of the Toast methods for me to use it. By default the Boast will cancel the previous one, so you don't build up a queue of Toasts waiting to be displayed.
If you just want to know how to cancel the notifications when exiting your app, you will find lots of help in there.
package mobi.glowworm.lib.ui.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.Nullable;
import android.widget.Toast;
import java.lang.ref.WeakReference;
/**
* {#link Toast} decorator allowing for easy cancellation of notifications. Use this class if you
* want subsequent Toast notifications to overwrite current ones. </p>
* <p/>
* By default, a current {#link Boast} notification will be cancelled by a subsequent notification.
* This default behaviour can be changed by calling certain methods like {#link #show(boolean)}.
*/
public class Boast {
/**
* Keeps track of certain Boast notifications that may need to be cancelled. This functionality
* is only offered by some of the methods in this class.
* <p>
* Uses a {#link WeakReference} to avoid leaking the activity context used to show the original {#link Toast}.
*/
#Nullable
private volatile static WeakReference<Boast> weakBoast = null;
#Nullable
private static Boast getGlobalBoast() {
if (weakBoast == null) {
return null;
}
return weakBoast.get();
}
private static void setGlobalBoast(#Nullable Boast globalBoast) {
Boast.weakBoast = new WeakReference<>(globalBoast);
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Internal reference to the {#link Toast} object that will be displayed.
*/
private Toast internalToast;
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Private constructor creates a new {#link Boast} from a given {#link Toast}.
*
* #throws NullPointerException if the parameter is <code>null</code>.
*/
private Boast(Toast toast) {
// null check
if (toast == null) {
throw new NullPointerException("Boast.Boast(Toast) requires a non-null parameter.");
}
internalToast = toast;
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Make a standard {#link Boast} that just contains a text view.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, CharSequence text, int duration) {
return new Boast(Toast.makeText(context, text, duration));
}
/**
* Make a standard {#link Boast} that just contains a text view with the text from a resource.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
* #throws Resources.NotFoundException if the resource can't be found.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, int resId, int duration)
throws Resources.NotFoundException {
return new Boast(Toast.makeText(context, resId, duration));
}
/**
* Make a standard {#link Boast} that just contains a text view. Duration defaults to
* {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, CharSequence text) {
return new Boast(Toast.makeText(context, text, Toast.LENGTH_SHORT));
}
/**
* Make a standard {#link Boast} that just contains a text view with the text from a resource.
* Duration defaults to {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #throws Resources.NotFoundException if the resource can't be found.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, int resId) throws Resources.NotFoundException {
return new Boast(Toast.makeText(context, resId, Toast.LENGTH_SHORT));
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Show a standard {#link Boast} that just contains a text view.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
*/
public static void showText(Context context, CharSequence text, int duration) {
Boast.makeText(context, text, duration).show();
}
/**
* Show a standard {#link Boast} that just contains a text view with the text from a resource.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
* #throws Resources.NotFoundException if the resource can't be found.
*/
public static void showText(Context context, int resId, int duration)
throws Resources.NotFoundException {
Boast.makeText(context, resId, duration).show();
}
/**
* Show a standard {#link Boast} that just contains a text view. Duration defaults to
* {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
*/
public static void showText(Context context, CharSequence text) {
Boast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
/**
* Show a standard {#link Boast} that just contains a text view with the text from a resource.
* Duration defaults to {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #throws Resources.NotFoundException if the resource can't be found.
*/
public static void showText(Context context, int resId) throws Resources.NotFoundException {
Boast.makeText(context, resId, Toast.LENGTH_SHORT).show();
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Close the view if it's showing, or don't show it if it isn't showing yet. You do not normally
* have to call this. Normally view will disappear on its own after the appropriate duration.
*/
public void cancel() {
internalToast.cancel();
}
/**
* Show the view for the specified duration. By default, this method cancels any current
* notification to immediately display the new one. For conventional {#link Toast#show()}
* queueing behaviour, use method {#link #show(boolean)}.
*
* #see #show(boolean)
*/
public void show() {
show(true);
}
/**
* Show the view for the specified duration. This method can be used to cancel the current
* notification, or to queue up notifications.
*
* #param cancelCurrent <code>true</code> to cancel any current notification and replace it with this new
* one
* #see #show()
*/
public void show(boolean cancelCurrent) {
// cancel current
if (cancelCurrent) {
final Boast cachedGlobalBoast = getGlobalBoast();
if ((cachedGlobalBoast != null)) {
cachedGlobalBoast.cancel();
}
}
// save an instance of this current notification
setGlobalBoast(this);
internalToast.show();
}
}
Make a java class as ShowToast.java like below
public class ShowToast {
private static Toast toast;
public static void show(Context mcontext, String text) {
if (toast != null)
toast.cancel();
toast = Toast.makeText(mcontext, text, Toast.LENGTH_SHORT);
toast.show();
}
}
Then call it as
ShowToast.show(getApplicationContext(),"YOUR_TOAST_TEXT");
cancel() doesn't do anything I'm afraid.
I would suggest using Crouton https://github.com/keyboardsurfer/Crouton
This my solution works perfect both for 4.* and 2.3 Android versions
static Toast toast;
.....
if (toast != null)
toast.cancel();
boolean condition = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
if ((toast == null && condition) || !condition)
toast = Toast.makeText(context, text, Toast.LENGTH_LONG);
if ((toast != null && condition))
toast.setText(text);
toast.show();
Create an Toast Object:
Toast toastobject=null;
Now use the below code to display the toast. This will work find for me
int index = clickCounter-1;
if(toastobject!= null)
{
toastobject.cancel();
}
toastobject = Toast.makeText(this,"Toast Text" , Toast.LENGTH_SHORT);
listItems.remove(index);
toastobject.show();
create new function and call this.
ImageButton ABtn = (ImageButton) findViewById(R.id.Btn);
ABtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
SETToast("mytext");
}
});
private Toast toast = null;
public void SETToast( String text)
{
if(toast==null)
{
toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
toast.show();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast=null;
}
}, 2000);
}
else
{
toast.setText(text);
}
}
Kotlin approach:
class MyActivity: Activity {
private var toast: Toast? = null
fun yourFunction() {
toast?.cancel()
toast = if(documentWasSaved) {
makeText(this, "Document was saved"), Toast.LENGTH_LONG)
} else {
makeText(this, "Failed to save your document", Toast.LENGTH_LONG)
}
toast?.show()
}
}
In my app, I construct a calendar widget for my activity, when I scroll it to previous or next month, I let it make a toast and show it.
The question is, the toast need time to show, when I scroll it fast enough, for example, I scrolled to "2012/05" and "2012/06" and scroll to "2012/07" without pause, I have to wait the Toast of "2012/05", "2012/06","2012/07" to show one by one slowly.
Seems like Android has an invisible queue to manage toasts
how can I clean it and only show the last toast? Can I show a specific Toast immediately without waiting?
I searched the "android.widget.Toast.java" and find a method cancel(), but unfortunately it does not work as follows.
if (t != null) {
t.cancel();
}
t = Toast.makeText(this.mContext, mHelper.getYear() + "年"
+ (mHelper.getMonth() + 1) + "月", Toast.LENGTH_SHORT);
t.show();
You just need to declare a "Toast" var like this:
Toast toastMessage;
Then in your function, do it like this:
if (toastMessage!= null) {
toastMessage.cancel();
}
toastMessage= Toast.makeText(context, "The message you want to display", duration);
toastMessage.show();
Here is my answer copied from another similar question here:
Android cancel Toast when exiting the app and when toast is being shown
The Boast class accomplishes exactly what you need. Most recent code can be found on GitHub here:
Boast.java
The trick is to keep track of the last Toast that was shown, and to cancel that one.
What I have done is to create a Toast wrapper, that contains a static reference to the last Toast displayed.
When I need to show a new one, I first cancel the static reference, before showing the new one (and saving it in the static).
Here's full code of the Boast wrapper I made - it mimics enough of the Toast methods for me to use it. By default the Boast will cancel the previous one, so you don't build up a queue of Toasts waiting to be displayed.
If you just want to know how to cancel the notifications when exiting your app, you will find lots of help in there.
package mobi.glowworm.lib.ui.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.Nullable;
import android.widget.Toast;
import java.lang.ref.WeakReference;
/**
* {#link Toast} decorator allowing for easy cancellation of notifications. Use this class if you
* want subsequent Toast notifications to overwrite current ones. </p>
* <p/>
* By default, a current {#link Boast} notification will be cancelled by a subsequent notification.
* This default behaviour can be changed by calling certain methods like {#link #show(boolean)}.
*/
public class Boast {
/**
* Keeps track of certain Boast notifications that may need to be cancelled. This functionality
* is only offered by some of the methods in this class.
* <p>
* Uses a {#link WeakReference} to avoid leaking the activity context used to show the original {#link Toast}.
*/
#Nullable
private volatile static WeakReference<Boast> weakBoast = null;
#Nullable
private static Boast getGlobalBoast() {
if (weakBoast == null) {
return null;
}
return weakBoast.get();
}
private static void setGlobalBoast(#Nullable Boast globalBoast) {
Boast.weakBoast = new WeakReference<>(globalBoast);
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Internal reference to the {#link Toast} object that will be displayed.
*/
private Toast internalToast;
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Private constructor creates a new {#link Boast} from a given {#link Toast}.
*
* #throws NullPointerException if the parameter is <code>null</code>.
*/
private Boast(Toast toast) {
// null check
if (toast == null) {
throw new NullPointerException("Boast.Boast(Toast) requires a non-null parameter.");
}
internalToast = toast;
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Make a standard {#link Boast} that just contains a text view.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, CharSequence text, int duration) {
return new Boast(Toast.makeText(context, text, duration));
}
/**
* Make a standard {#link Boast} that just contains a text view with the text from a resource.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
* #throws Resources.NotFoundException if the resource can't be found.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, int resId, int duration)
throws Resources.NotFoundException {
return new Boast(Toast.makeText(context, resId, duration));
}
/**
* Make a standard {#link Boast} that just contains a text view. Duration defaults to
* {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, CharSequence text) {
return new Boast(Toast.makeText(context, text, Toast.LENGTH_SHORT));
}
/**
* Make a standard {#link Boast} that just contains a text view with the text from a resource.
* Duration defaults to {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #throws Resources.NotFoundException if the resource can't be found.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, int resId) throws Resources.NotFoundException {
return new Boast(Toast.makeText(context, resId, Toast.LENGTH_SHORT));
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Show a standard {#link Boast} that just contains a text view.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
*/
public static void showText(Context context, CharSequence text, int duration) {
Boast.makeText(context, text, duration).show();
}
/**
* Show a standard {#link Boast} that just contains a text view with the text from a resource.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
* #throws Resources.NotFoundException if the resource can't be found.
*/
public static void showText(Context context, int resId, int duration)
throws Resources.NotFoundException {
Boast.makeText(context, resId, duration).show();
}
/**
* Show a standard {#link Boast} that just contains a text view. Duration defaults to
* {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
*/
public static void showText(Context context, CharSequence text) {
Boast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
/**
* Show a standard {#link Boast} that just contains a text view with the text from a resource.
* Duration defaults to {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #throws Resources.NotFoundException if the resource can't be found.
*/
public static void showText(Context context, int resId) throws Resources.NotFoundException {
Boast.makeText(context, resId, Toast.LENGTH_SHORT).show();
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Close the view if it's showing, or don't show it if it isn't showing yet. You do not normally
* have to call this. Normally view will disappear on its own after the appropriate duration.
*/
public void cancel() {
internalToast.cancel();
}
/**
* Show the view for the specified duration. By default, this method cancels any current
* notification to immediately display the new one. For conventional {#link Toast#show()}
* queueing behaviour, use method {#link #show(boolean)}.
*
* #see #show(boolean)
*/
public void show() {
show(true);
}
/**
* Show the view for the specified duration. This method can be used to cancel the current
* notification, or to queue up notifications.
*
* #param cancelCurrent <code>true</code> to cancel any current notification and replace it with this new
* one
* #see #show()
*/
public void show(boolean cancelCurrent) {
// cancel current
if (cancelCurrent) {
final Boast cachedGlobalBoast = getGlobalBoast();
if ((cachedGlobalBoast != null)) {
cachedGlobalBoast.cancel();
}
}
// save an instance of this current notification
setGlobalBoast(this);
internalToast.show();
}
}
You need to call method on correct object.
toastObject.cancel()
Here is the Code.
final Toast toastobject = Toast.makeText(context, "This message will disappear when toast.close(); is called", Toast.LENGTH_SHORT);
Now you can use the Object of toastobject. Its Reference
toastobject.cancel();
You can use it in Thread or whenever you would like to Close the Toast.
You can reuse a toast, this will make it display immediately.
myToast.setText(toastMsg);
myToast.show();
There are many ways by which we can cancel previous Toast when we want to show another Toast. below I have written a simplest an easy way to implement it. First of all, we have to create a variable which can be accessed in the whole class.
private Toast toast;
After creating the variable which can be accessed by whole class we have to create a method in our class which displays the toast message and checks if the previous toast is displaying then cancel it.
public void showToast(String message) {
if (toast != null) {
toast.cancel();
}
toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT);
toast.show();
}
you can change toast message by runtime calling above method.
showToast("message 1");
//after some time
showToast("message 2");
hope it helps.
Toast has a method to hide current toast message
public void cancel() {
mTN.hide();
}
Try calling t.cancel() when it is necessary.
You can create static method and use it to show a toast:
public static Toast toast = null;
public static showToast(Context context,String msg){
if(toast!=null) //this will cancel the toast on the screen if one exists
toast.cancel();
toast = Toast.makeText(context,msg);
toast.show();
}
Simple. Simply call the method .cancel() on the toast once you want to create another toast.
Start by defining a Toast variable at the top of your class like this
private Toast mToast;
Later, When you want to create a new Toast(and have the old one disappear),
do this.
if(mToast != null) {
mToast.cancel(); //if a toast exists it deletes it, allowing you to create a new one
}
mToast = Toast.makeText(this, "This will show up now!", Toast.LENGTH_LONG);
mToast.show(); //creates the new toast.
public static Toast sToast=null;
// create Toast object;
public void showToast(String msg)
{
//here is checking whether toast object is null or not;if not null gonna cancel the toast that is showing in phone window and make it null;
if(sToast!=null)
{
sToast.cancel;
sToast=null;
}
//if toast object is null,gonna create new instance and make it shown on phone window.
if(sToast==null)
{
sToast=Toast.makeText(currentActivity.this,msg,Duration);
sToast.setGravity();
sToast.show();
}
}
Belatedly:
The reason your code doesn't work is that Toast.makeText() does not return a reference to the Toast it is creating. It is just a helper method designed to allow Toast to be created quickly and easily, but doesn't allow for reference or cancellation. To cancel, you would have to do:
t=Toast(requireContext())
t.setText(YOUR TEXT)
t.setDuration(1000)
t.show()
This way t would be assigned a reference when the constructor was called, which would allow for cancellation later.
You can use one shoot technique. Oke let's start defining:
private Toast mToast;
private showOnce=false;
Later when you wanna show toast once:
if(showOnce==false){
mToast=Toast.makeText(this, "Once!", Toast.LENGTH_LONG);
mToast.show();
showOnce=true;
}