问题
I have a toast message that doesn't disappear after execution. Im guessing it has something to do with it being in the loop but I'm not sure. Can someone help me figure out what why the toast message doesn't disparate?
@Override
public void onClick(View v) {
int index = 0;
for(int i= 0; i<userArray.length; i++){
if(email.getText().toString().equals(userArray[i])){
index = i;
}
if(passArray[index].equals(password.getText().toString())){
Toast.makeText(getBaseContext(), "SUCCESS!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getBaseContext(), "INVALID LOGIN", Toast.LENGTH_SHORT).show();
}
}
Intent mainIntent = new Intent(LoginActivity.this, MainActivity.class);
startActivityForResult(mainIntent, 0);
}
}
回答1:
A Toast message can become stuck if you call it from a Service thread and that thread completes it's work before Toast is set to disappear. You are then stuck with the Toast message on the screen until you kill the app.
回答2:
Toast
always disappears. Always.
Therefore, you are displaying multiple Toast messages. Guaranteed. Test this by changing the messages with some sort of counter or disabling after the initial one is displayed.
Note that quite a few Toasts can stack up and take a loooooong time to finish showing back-to-back. Wait and they will eventually go away as long as your app isn't looping indefinitely.
Edit: I stant corrected. Apparently, Toast
messages can get stuck and remain displayed if started from a Thread, Service, or IntentService. Thank you @Johnathan and @zapotec.
回答3:
A Toast
does not always disappear.
"If you call it from a Service thread and that thread completes it's work before Toast is set to disappear, you are stuck with the Toast message on the screen until you kill the app."
(copied from original answer by Jonathan Cole, which was unfortunately removed)
Here is a sample stack trace that explains how the situation can occur:
java.lang.IllegalStateException: Handler (android.os.Handler) {123f93ea} sending message to a Handler on a dead thread
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:325)
at android.os.Handler.enqueueMessage(Handler.java:631)
at android.os.Handler.sendMessageAtTime(Handler.java:600)
at android.os.Handler.sendMessageDelayed(Handler.java:570)
at android.os.Handler.post(Handler.java:326)
at android.widget.Toast$TN.hide(Toast.java:387)
at android.widget.Toast.cancel(Toast.java:133)
回答4:
I had this problem. What I found is that I instantiated over 10 toasts. Each waited till the next one faded before displaying the next, with a total 20 seconds on screen.
I found that storing all toasts in an arraylist, then canceling them all fix my problem.
private ArrayList<Toast> toasts;
public void sendToast(final String message) {
if (null == toasts) {
toasts = new ArrayList<Toast>();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
Toast toast = Toast.makeText(NJActivity.this, message, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.TOP|Gravity.CENTER, 0, 300);
toast.show();
toasts.add(toast);
} catch(Exception e) {/* do nothing, just means that the activity doesn't exist anymore*/}
}
});
}
public void removeToast() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (null != toasts) {
for(Toast toast:toasts) {
toast.cancel();
}
toasts = null;
}
}
});
}
Then on destroy on stop I called the removeToast() method
@Override
public void onDestroy() {
super.onDestroy();
removeToast();
}
@Override
protected void onStop () {
super.onStop();
removeToast();
}
回答5:
There are some weird cases that the toast won't disappear. In order to handle this, just use the Handler. Create one as a field, and use "post(Runnable)" with the toast being shown there.
回答6:
Here’s my solution with a custom toast handler. Works perfectly in m app.
public class CustomToast {
private LayoutInflater inflater;
private Toast toast;
private View customToastLayout;
private TextView LblCustomToast;
public CustomToast() {}
public void showCustomToast(String toastMessage, int toastLength, AppCompatActivity context) {
if(inflater == null) {inflater = context.getLayoutInflater();}
if(customToastLayout == null) {customToastLayout = inflater.inflate(R.layout.toast_layout, (ViewGroup) context.findViewById(R.id.toast_layout_root));}
if(LblCustomToast == null) {LblCustomToast = (TextView) customToastLayout.findViewById(R.id.LblCustomToast);}
LblCustomToast.setText(toastMessage);
if(toast == null) {toast = new Toast(context);}
toast.setGravity(Gravity.CENTER_VERTICAL| Gravity.BOTTOM, 0, DPDensity.getPxFromDP(160, context.getResources()));
toast.setDuration(toastLength);
toast.setView(customToastLayout);
if(toast.getView().isShown()) {toast.cancel();}//Toast is cancelled here if currently showing
toast.show();
}
}
Here is the XML Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toast_layout_root"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingTop="5dp"
android:paddingRight="15dp"
android:paddingBottom="5dp"
android:orientation="vertical"
android:background="@drawable/custom_toast_bg"
android:gravity="bottom|center"
android:layout_marginBottom="50dp">
<TextView android:id="@+id/LblCustomToast"
android:text="Test"
android:textSize="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/lightLime"
android:layout_gravity="center"
android:gravity="center"/>
</LinearLayout>
And here is the Usage:
customToast = new CustomToast();
customToast.showCustomToast(getString(R.string.your_message), Toast.LENGTH_SHORT, (AppCompatActivity) mainActivityContext);
回答7:
I had same problem before and here is what helped me. I created my Toast in onCreate, like this
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
Context context = getApplicationContext();
CharSequence text = "~I'm a toast that will dissapear~!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.setGravity(Gravity.TOP, 0, 0);}
And then I simply called it from methods that run on the different thread as
toast.show();
I hope it can help!
P.S. I think the problem was that your toast was created on one thread and called from another (uithread)
回答8:
I m guessing it has something to do with it being in the loop but I'm not sure.
Yes you are right its appearing beacause you have kept it in for
loop so as many times the loop will execute that many time the Toast
will appear.
You are showing the Toast multiple times in your code.
I would be better if your don't want toast multiple times then you can write it out side the for loop.
回答9:
I think the issue is toast is appearing again and again on screen and its taking the time to dismiss. Check your code bye putting the toast outside loop and also check if the conditions are true multiple times. In short just DEBUG
your code.
回答10:
Toast stays a little longer. It will always disappear once generated. As in loop they are getting continuously generated upon each other, so its giving you the illusion of being there always. if you will remain patient and wait for a little long all will disappear after some time.
If you want to show success message.
Try making alert dialogue
and keep on updating message their on some Text View
the success message that you want to show on success and failure.
or try raising Toast
only when it fails to login.
Or check for Infintie Loop
if you want to stick to the same approach
来源:https://stackoverflow.com/questions/15540416/persistent-toast-message-toast-wont-disappear-after-execution