Кнопка в пользовательском Android Toast? - PullRequest
27 голосов
/ 22 июля 2010

Можно ли иметь кнопку в тосте?

В теории да, потому что вы можете создать собственный тост из макета в XML, но я попытался вставить в него кнопку и не смог заставить его зарегистрировать щелчок.Кому-нибудь удалось сделать что-то подобное?

Ответы [ 8 ]

34 голосов
/ 22 июля 2010

Тост не может быть нажата. Невозможно захватить щелчок внутри сообщения тоста. Вам нужно будет построить диалог для этого. Посмотрите Создание диалогов для получения дополнительной информации.

API в классе Toast сообщает, что тост никогда не получит фокус, а поскольку тост не является представлением, сообщения onClick нет. Я бы предположил, что поэтому нельзя нажимать и на детей тоста.

19 голосов
/ 19 августа 2012

Тост не может содержать кнопку.За исключением того, что приложение gmail и приложение галереи в желейных бобах имеют полутост, содержащий кнопку, вот как Google это сделал

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

Полагаю, это отвечает на ваш вопрос.

8 голосов
/ 18 октября 2014

Фрагмент показывает реализацию пользовательского тоста, который:

Header

  • Интерфейс похож на оригинальный 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
Пост, показывающий реализацию пользовательского макета в этом посте

4 голосов
/ 25 февраля 2014

Пользовательский вид, передаваемый тосту, может содержать что угодно;однако тосты не могут получать события касания, поэтому никакие компоненты, использующие события касания, не будут работать в обычном тосте (кнопки, радиокнопки и т. д.).Единственный выбор, который у вас есть, - это создать собственный вид с кнопкой в ​​нем и добавить его в свой макет.Есть много примеров того, как это сделать, и несколько библиотек, которые вы можете проверить, чтобы узнать, как это делают другие люди.

UndoBar
MessageBar
UndoBar Нурика

Конечно, вы также можетеиспользуйте библиотеку SuperToasts , которую я собрал, но это может быть немного излишним для одного использования.То, как я это делаю, описано в классе SuperActivityToast .

1 голос
/ 29 февраля 2016

Вы можете попробовать SuperToast в этом случае.Это может создать тост с кнопкой.Он имеет особенность длительности, красочный фон, красочные шрифты, пользовательские шрифты, анимированный эффект.Надеюсь, вам понравится

1 голос
/ 01 августа 2015

Вы должны использовать Snackbar. Он находится в последней библиотеке поддержки Android (на момент ответа) и совместим со старыми уровнями API. Это гораздо проще реализовать, чем Dialog или пользовательский View, и имеет возможность иметь кнопку в отличие от Toast.

  1. Загрузка Android Support Library из Extras в SDK Manager (ревизия 22.2.1 или более поздняя).
  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. Я использовал его в одном из своих проектов, и он прекрасно работает.

0 голосов
/ 14 октября 2014

Создание системного оверлейного окна (всегда сверху)

Это говорит о том, что это можно сделать, мне также нужны кнопки в тосте, поэтому мне все еще нужно сделать свою собственную реализацию,Если я найду больше, я добавлю его в свой пост

0 голосов
/ 30 сентября 2013

Используйте окно оповещения, если хотите добавить кнопку :-).Вот несколько примеров Диалоговые окна в Android

...