30

吐司可以有按钮吗?

理论上,是的,因为您可以从 XML 中的布局构建自定义 Toast,但我试图在其中放置一个按钮,但无法让它注册点击。有没有人设法做这样的事情?

4

8 回答 8

39

无法点击吐司。无法在 toast 消息中捕获点击。您将需要为此构建一个对话框。查看创建对话框了解更多信息。

Toast类上的 API声明 toast 永远不会获得焦点,并且因为 toast 不是视图,所以没有 onClick 消息。我会假设因此也不能单击 Toast 的子级。

于 2010-07-22T13:00:27.760 回答
20

吐司不能包含按钮。除了 gmail 应用程序和 jelly beans 中的画廊应用程序有一个包含按钮的半吐司之外,谷歌是这样做的

https://gist.github.com/benvd/4090998

我想这回答了你的问题。

于 2012-08-19T09:31:07.123 回答
9

片段显示了自定义 Toast 的实现:

标题

  • 具有与原始Toast类相似的界面
  • 可用作Dialog(具有 Gmail 应用程序等可点击按钮)
  • 有可能length进入millis
  • 可以设置显示和取消动画
  • 只存在于初始化Activity

当前限制:

  • 不支持屏幕方向更改

用法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...

    View toastView = new View(getBaseContext());
    //init your toast view

    ActivityToast toast = new ActivityToast(this, toastView);

    //set toast Gravity ( Gravity.BOTTOM | Gravity.FILL_HORIZONTAL by default)
    toast.setGravity(Gravity.CENTER);

    toast.setLength(10000); //set toast show duration to 10 seconds (2 seconds by default)

    Animation showAnim; // init animation
    Animation.AnimationListener showAnimListener; //init anim listener
    toast.setShowAnimation(showAnim);
    toast.setShowAnimationListener(showAnimListener);

    Animation cancelAnim; // init animation
    Animation.AnimationListener cancelAnimListener; //init anim listener
    toast.setCancelAnimation(showAnim);
    toast.setCancelAnimationListener(showAnimListener);

    toast.show(); //show toast view
    toast.isShowing(); // check if toast is showing now
    toast.cancel(); //cancel toast view

    toast.getView(); //get toast view to update it or to do something ..
}

来源

import android.app.Activity;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.FrameLayout;

public class ActivityToast {

    public static final long LENGTH_SHORT = 2000;
    public static final long LENGTH_LONG = 3000;
    public static final int DEFAULT_ANIMATION_DURATION = 400;

    private final Activity mActivity;
    private FrameLayout.LayoutParams mLayoutParams;

    private Handler mHandler = new Handler();

    private ViewGroup mParent;
    private FrameLayout mToastHolder;
    private View mToastView;

    private Animation mShowAnimation;
    private Animation mCancelAnimation;

    private long mLength = LENGTH_SHORT;

    private Animation.AnimationListener mShowAnimationListener;
    private Animation.AnimationListener mCancelAnimationListener;

    private boolean mIsAnimationRunning;
    private boolean mIsShown;

    /**
     * @param activity Toast will be shown at top of the widow of this Activity
     */
    public ActivityToast(@NonNull Activity activity, View toastView) {
        mActivity = activity;

        mParent = (ViewGroup) activity.getWindow().getDecorView();
        mToastHolder = new FrameLayout(activity.getBaseContext());
        mLayoutParams = new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT,
                Gravity.BOTTOM | Gravity.FILL_HORIZONTAL
        );
        mToastHolder.setLayoutParams(mLayoutParams);

        mShowAnimation = new AlphaAnimation(0.0f, 1.0f);
        mShowAnimation.setDuration(DEFAULT_ANIMATION_DURATION);
        mShowAnimation.setAnimationListener(mHiddenShowListener);

        mCancelAnimation = new AlphaAnimation(1.0f, 0.0f);
        mCancelAnimation.setDuration(DEFAULT_ANIMATION_DURATION);
        mCancelAnimation.setAnimationListener(mHiddenCancelListener);

        mToastView = toastView;
        mToastHolder.addView(mToastView);

        mToastHolder.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                    cancel();
                }
                return false;
            }
        });
    }

    public void show() {
        if (!isShowing()) {
            mParent.addView(mToastHolder);
            mIsShown = true;

            if (mShowAnimation != null) {
                mToastHolder.startAnimation(mShowAnimation);
            } else {
                mHandler.postDelayed(mCancelTask, mLength);
            }
        }
    }

    public void cancel() {
        if (isShowing() && !mIsAnimationRunning) {
            if (mCancelAnimation != null) {
                mToastHolder.startAnimation(mCancelAnimation);
            } else {
                mParent.removeView(mToastHolder);
                mHandler.removeCallbacks(mCancelTask);
                mIsShown = false;
            }
        }
    }

    public boolean isShowing() {
        return mIsShown;
    }

    /**
     * Pay attention that Action bars is the part of Activity window
     *
     * @param gravity Position of view in Activity window
     */

    public void setGravity(int gravity) {
        mLayoutParams.gravity = gravity;

        if (isShowing()) {
            mToastHolder.requestLayout();
        }
    }

    public void setShowAnimation(Animation showAnimation) {
        mShowAnimation = showAnimation;
    }

    public void setCancelAnimation(Animation cancelAnimation) {
        mCancelAnimation = cancelAnimation;
    }

    /**
     * @param cancelAnimationListener cancel toast animation. Note: you should use this instead of
     *                                Animation.setOnAnimationListener();
     */
    public void setCancelAnimationListener(Animation.AnimationListener cancelAnimationListener) {
        mCancelAnimationListener = cancelAnimationListener;
    }

    /**
     * @param showAnimationListener show toast animation. Note: you should use this instead of
     *                              Animation.setOnAnimationListener();
     */
    public void setShowAnimationListener(Animation.AnimationListener showAnimationListener) {
        mShowAnimationListener = showAnimationListener;
    }

    public void setLength(long length) {
        mLength = length;
    }

    public View getView() {
        return mToastView;
    }

    private Runnable mCancelTask = new Runnable() {
        @Override
        public void run() {
            cancel();
        }
    };

    private Animation.AnimationListener mHiddenShowListener = new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
            if (mShowAnimationListener != null) {
                mShowAnimationListener.onAnimationStart(animation);
            }

            mIsAnimationRunning = true;
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            mHandler.postDelayed(mCancelTask, mLength);

            if (mShowAnimationListener != null) {
                mShowAnimationListener.onAnimationEnd(animation);
            }

            mIsAnimationRunning = false;
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            if (mShowAnimationListener != null) {
                mShowAnimationListener.onAnimationRepeat(animation);
            }
        }
    };

    private Animation.AnimationListener mHiddenCancelListener = new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
            if (mCancelAnimationListener != null) {
                mCancelAnimationListener.onAnimationStart(animation);
            }

            mIsAnimationRunning = true;
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            mParent.removeView(mToastHolder);
            mHandler.removeCallbacks(mCancelTask);

            if (mCancelAnimationListener != null) {
                mCancelAnimationListener.onAnimationEnd(animation);
            }

            mIsAnimationRunning = false;
            mIsShown = false;
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            if (mCancelAnimationListener != null) {
                mCancelAnimationListener.onAnimationRepeat(animation);
            }
        }
    };
}

我在 github
Post 上的原始帖子显示了此帖子中自定义布局的实现

于 2014-10-18T08:20:09.280 回答
5

传递给 toast 的自定义视图可以包含任何内容;但是,toast 无法接收任何触摸事件,因此使用触摸事件的组件不会在普通 toast(按钮、单选按钮等)中工作。您唯一的选择是创建一个带有按钮的自定义视图并将其添加到您的布局中。有很多关于如何做到这一点的示例,您可以查看一些库以了解其他人是如何做到这一点的。

UndoBar
MessageBar
Nurik 的 UndoBar

当然,也欢迎您使用我放在一起的SuperToasts库,但是对于一种用法可能有点矫枉过正。我这样做的方式在SuperActivityToast类中进行了概述。

于 2014-02-24T21:15:30.033 回答
3

您应该使用Snackbar. 它位于最新的 android 支持库中(在回答时),并且与旧的 api 级别兼容。它比 aDialog或 custom更容易实现View,并且具有与 a 不同的按钮的能力Toast

  1. Android Support Library从(修订版 22.2.1 或更高版本)Extras中下载。SDK Manager
  2. 在将此build.gradle添加到类依赖项中:com.android.support:design:22.2.0.
  3. 实施:

    Snackbar.make(this.findViewById(android.R.id.content), "Toast Message", Snackbar.LENGTH_LONG) .setAction("Click here to activate action", onClickListener) .setActionTextColor(Color.RED) .show;

就是这样。没有 github 项目和实现非常类似于Toast. 我在我的一个项目中使用了它,效果很好。

于 2015-08-01T00:01:56.813 回答
2

在这种情况下,您可以尝试SuperToast 。它可以用按钮创建吐司。它具有自定义持续时间功能,彩色背景,彩色字体,自定义字体,动画效果。希望你会喜欢它

于 2016-02-29T06:02:21.973 回答
1

如果要添加按钮,请使用警报框:-)。以下是 Android 中的一些示例 对话框

于 2013-09-30T14:52:16.233 回答
1

创建系统覆盖窗口(始终在顶部)

这表明它可以完成,我还需要祝酒词中的按钮,所以我仍然必须自己实现。如果我发现更多,我会把它添加到我的帖子中

于 2014-10-14T10:43:22.690 回答