android 如何防止多个吐司重叠

d4so4syb  于 2023-02-06  发布在  Android
关注(0)|答案(9)|浏览(192)

我一直在使用一个常见的“myToast”,在发出新的toast之前,我使用“myToast.cancel()”。对于Android v2.3和更早的版本,这个功能非常好。当需要发送新的toast时,如果旧的toast还在屏幕上,被取消(并立即消失)以替换为新的吐司。如果用户多次按下需要提醒的键,这可以避免堆积一堆toast(和其他条件)。我的实际情况是按错键时出现一个吐司,没有按清除键时出现另一个吐司。
对于Android 4.0和4.1,在下一个吐司之前发出myToast.cancel()会同时取消当前和下一个toast。当前的cancel() API确实指示它取消当前和下一个toast(这似乎相当愚蠢)。为什么要取消要发出的toast呢?
有没有什么想法可以让取消功能在Android版本中保持一致(以及在v2.3及更早版本中的工作方式)?
我会尝试一些不优雅的双吐司系统,跟踪哪些吐司正在使用,但它似乎是这样一个痛苦的工作,围绕这种不良行为在4.x中得到什么工作完美和逻辑在旧的Android版本。
好了,我解决了这个问题,但是它并没有我希望的那么干净。我实现了一个双吐司方法,它在两个toast之间交替。首先,我们为OnCreate之前的Activity定义toast:

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

在创建时:

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

最后,当我需要同时显示吐司和取消之前的toast时,我使用类似于以下内容的代码:

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)、模拟器4.0和几台Android 2.2、2.3设备上进行测试。

nbewdwxp

nbewdwxp1#

不要调用cancel()。尝试重置文本并调用show()。这将自动取消最后一个吐司

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

如果您继续使用相同的myToast,而不是每次都创建一个,我猜它们不会堆叠起来。

xvw2m8pv

xvw2m8pv2#

难道nandeesh的解决方案对你不起作用吗?他的解决方案比用两种不同的吐司要干净。
例如,(扩展他/她的答案)在onCreate之前,我们会声明吐司:

private Toast myToast;

在onCreate中我们必须使用makeToast初始化它(否则我们会得到一个错误):

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

每当我们想播放吐司时,我们只需调用:

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

这将取代之前的吐司。

vxqlmq5t

vxqlmq5t3#

以下是我从另一个类似问题中抄来的答案:

Boast类正好完成了您所需要的。
诀窍是跟踪显示的最后一个Toast,然后取消那个。
我所做的是创建一个Toast Package 器,它包含对最后显示的吐司的静态引用。
当我需要显示一个新对象时,我首先取消静态引用,然后再显示新对象(并将其保存在静态中)。
下面是我制作的Boast Package 器的完整代码--它模仿了吐司方法的很多部分,我可以使用它。默认情况下,Boast将取消前一个方法,因此您不会建立等待显示的Toast队列。
如果你只是想知道如何在退出应用程序时取消通知,你会在那里找到很多帮助。

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

}
wmtdaxz3

wmtdaxz34#

创建一个java类***ShowToast.java***,如下所示

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

那就叫它

ShowToast.show(getApplicationContext(),"YOUR_TOAST_TEXT");
ifsvaxew

ifsvaxew5#

cancel()恐怕什么也做不了。
我建议使用Crouton https://github.com/keyboardsurfer/Crouton

fjaof16o

fjaof16o6#

这是我的解决方案工程完美的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();
7cjasjjr

7cjasjjr7#

创建吐司对象:

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

qlvxas9a8#

创建一个新函数并调用它。

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

k75qkfdt9#

Kotlin方法:

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

相关问题