2012-10-16 59 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();