2012-10-16 97 views
19

我一直在使用「myToast」,我使用「myToast.cancel();在發佈新的Toast之前,對於Android v2.3及更高版本,這很有用。新的吐司需要發送,舊的,如果仍然在屏幕上,被取消(並立即消失),以新的吐司替代。這避免堆疊一堆吐司,如果用戶多次按下一個鍵需要(或其他條件),我的實際情況是當按下錯誤的按鍵時出現一個烤麪包,如果沒有按下清除鍵,則出現另一個烤麪包如何防止多次吐司重疊

對於Android 4.0和4.1,發出myToast.cancel()在下一個吐司殺死當前和下一個吐司之前,當前的cancel()API確實表明它取消了當前和下一個吐司(這看起來相當愚蠢)。爲什麼要取消你想要舉辦的祝酒?

關於在Android版本(以及它在v2.3及更舊版本中的工作方式)中一致地取消工作的任何想法?

我會嘗試一些不雅的雙烤麪包系統,跟蹤哪個烤麪包正在使用,但看起來這樣的痛苦在4.x中解決這個不良行爲,以便在老版本的Android版本中得到完美和邏輯的效果。


好吧,我解決了它,但它幾乎沒有我所希望的那麼幹淨。我實施了雙烤麪包方法,在兩面烤麪包之間切換。首先,我們之前的OnCreate定義敬酒的活動:

Toast toast0; 
Toast toast1; 
private static boolean lastToast0 = true; 

在OnCreate:

toast0 = new Toast(getApplicationContext()); 
toast0.cancel(); 
toast1 = new Toast(getApplicationContext()); 
toast1.cancel(); 

最後,當我需要顯示敬酒,並在同一時間取消了之前敬酒我使用類似的東西:

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; 
} 

如果您只是需要取消現有吐司(超時之前)使用方法:

toast0.cancel(); 
toast1.cancel(); 

在Nexus 7(4.1),Emulator 4.0和幾款採用Android 2.2,2.3的設備上測試。

+0

你是如何取消舊吐司?在做新的之前或之後? – TheZ

+0

你可以發佈你的代碼在哪裏做烘烤? – Ralgha

+0

我在新的版本之前取消了它 - 這就是爲什麼Android 4.x隱藏新版本是如此奇怪(但是用於吐司的API會取消某種解釋將會發生)。我編輯了一個我創建的解決方案。只是不太好看。 – Frank

回答

47

而不是調用取消。嘗試重置文本並調用show()。這應該通過自身

myToast.setText("wrong key") 
myToast.show(); 

取消最後敬酒如果繼續使用相同的myToast,而不是創建一個每次我想他們不會疊起來。

+0

完美!感謝分享:) – Jona

2

cancel()我不害怕。

我會建議使用Crouton https://github.com/keyboardsurfer/Crouton

+0

圖書館是好的,但它不能解決這個問題。 – Ahmad

+0

在新的敬酒之前使用toast.cancel()部分地工作 - 現有的敬酒如果存在消失。在Android 4.x(也許是3.x)中發生了什麼變化,它也隱藏了我想替換第一個! – Frank

2

難道nandeesh的解決方案不適合你?他的解決方案比使用兩種不同的吐司更清潔。

例如,前(他/她的回答擴)到OnCreate中我們會宣佈敬酒:

private Toast myToast; 

和的onCreate我們不得不使用它來makeToast初始化(否則我們會得到錯誤):

myToast = Toast.makeText(getApplicationContext(), null, Toast.LENGTH_SHORT); 

,每當我們想顯示乾杯我們只需撥打:

myToast.setText("some text"); 
myToast.show(); 

,這將正確地取代以前的烤麪包片。

+0

我不確定你在哪裏閱讀Nandeesh建議使用兩個吐司,他明確地說'如果你繼續使用相同的myToast,而不是每次創建一個,我猜他們不會疊加起來。「在那一點上,我看不出你的答案和他的。另外,我建議你寫下你的答案,而不要將你的答案與其他人的答案進行比較。這對我來說聽起來很粗魯,特別是當你說他們的答案是錯的時候。 – ForceMagic

+0

我在哪裏說nandeesh使用兩個吐司? 此外,我的答案只是擴展他的並給出一個更長的例子。 – TSL

+0

對不起,這仍然讓我困惑Nandeesh的解決方案不適合你嗎?他的解決方案比使用兩種不同的吐司更清潔。「我不知道你爲什麼指出他的答案,然後發佈類似的答案,我的意思是他的答案中缺少的部分不會使其」不工作「 IMO。 – ForceMagic

2

,這裏是我的答案從這裏另一個類似的問題複製:

Boast類實現正是你需要的。


訣竅是跟蹤顯示的最後Toast,並取消那一個。

我所做的是創建一個Toast包裝,它包含對最後Toast顯示的靜態引用。

當我需要顯示一個新的,我首先取消靜態引用,然後顯示新的(並保存在靜態)。

以下是我製作的Boast包裝的完整代碼 - 它足以模仿Toast方法以供我使用。默認情況下,Boast將取消前一個,所以你不會建立一個等待顯示的Toasts隊列。

如果您只是想知道如何在退出應用時取消通知,那麼您會在該處找到很多幫助。


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(); 
    } 

} 
+0

我喜歡你的解決方案,它在4.x上工作正常,但你有什麼想法爲什麼它不能在2.x上工作? (我還沒有試過3.x) –

+0

對不起,沒有想法。這是生產代碼,我認爲我已經測試過它的向後兼容性。如果將來找到任何東西,將會重新發布。 –

1

這是我的解決方案既爲4 * 2.3的Android版本

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(); 
0

創造新的功能,稱之爲完美的作品。

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); 
    } 
} 
1

創建吐司對象:

Toast toastobject=null; 

現在使用下面的代碼顯示敬酒。這將工作找我

int index = clickCounter-1; 


    if(toastobject!= null) 
      { 
       toastobject.cancel(); 
      } 
      toastobject = Toast.makeText(this,"Toast Text" , Toast.LENGTH_SHORT); 
      listItems.remove(index); 
      toastobject.show();