web-dev-qa-db-fra.com

Bouton dans Android Toast personnalisé?

Est-il possible d'avoir un bouton dans un pain grillé?

En théorie, oui, car vous pouvez créer un Toast personnalisé à partir d'une présentation en XML, mais j'ai essayé d'y insérer un bouton et je n'ai pas pu l'obtenir pour enregistrer le clic. Est-ce que quelqu'un a réussi à faire quelque chose comme ça?

27
Sephy

Un pain grillé ne peut pas être cliqué. Il n'est pas possible de capturer un clic dans un message de pain grillé. Vous devrez créer un dialogue pour cela. Regardez Création de dialogues pour plus d’informations.

L'API sur l'état Toast class indique qu'un pain grillé ne recevra jamais le focus et qu'un pain grillé n'est pas une vue, il n'y a pas de message onClick. Je suppose donc que les enfants d'un pain grillé ne peuvent pas être cliqués aussi.

34
Janusz

Un toast ne peut pas contenir un bouton. Sauf que l'application gmail et l'application galerie dans Jelly Beans ont un semi-pain grillé qui contient un bouton. Voici comment Google l'a fait.

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

Je suppose que cela répond à votre question.

19
Hazem Farahat

Snippet montre l'implémentation de Toast personnalisé qui:

Header

  • Avoir une interface similaire à celle de la classe Toast originale
  • Peut être utilisé comme Dialog (avoir des boutons cliquables comme l’application Gmail)
  • Avoir la possibilité de mettre length dans millis
  • Avoir la possibilité de mettre en spectacle et d'annuler l'animation
  • Vit seulement avec Activity initialisé

Limitations actuelles:

  • Aucun changement d'orientation de l'écran n'est pris en charge

Usage:

@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 ..
}

Sources

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

Mon message original sur github
Message montrant la mise en œuvre de la disposition personnalisée dans ce message

8
Yakiv Mospan

Une vue personnalisée transmise à un toast peut contenir n'importe quoi; Cependant, les toasts ne peuvent recevoir aucun événement tactile. Par conséquent, aucun composant utilisant des événements tactiles ne fonctionnera dans un pain grillé standard (boutons, boutons radio, etc.). Le seul choix que vous avez est de créer une vue personnalisée avec un bouton et de l'ajouter à votre mise en page. Il existe de nombreux exemples sur la façon de procéder et quelques bibliothèques que vous pouvez consulter pour voir comment les autres le font.

UndoBar
MessageBar
Barre d'annulation de Nurik

Bien sûr, vous êtes également invités à utiliser la bibliothèque SuperToasts que j’ai construite, mais il est possible qu’elle soit un peu exagérée pour une utilisation. La façon dont je le fais est décrite dans la classe SuperActivityToast .

4
John P.

Vous devriez utiliser une Snackbar. Il se trouve dans la dernière bibliothèque de support Android (au moment de la réponse) et est compatible avec les anciens niveaux de l'API. Il est beaucoup plus facile à implémenter qu’un Dialog ou un View personnalisé et a la possibilité d’avoir un bouton contrairement à un Toast.

  1. Téléchargez Android Support Library de Extras dans le SDK Manager (révision 22.2.1 ou ultérieure).
  2. Dans le build.gradle, ajoutez ceci aux dépendances de la classe: com.Android.support:design:22.2.0.
  3. Mettre en place:

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

Et c'est ça. Aucun projet github et sa mise en œuvre ne ressemble beaucoup à Toast. Je l'ai utilisé dans l'un de mes projets et cela fonctionne très bien.

1
Dylan Vander Berg

Vous pouvez essayer SuperToast dans ce cas. Il peut créer un pain grillé avec un bouton. Il a une fonction de durée personnalisée, un fond coloré, des polices colorées, des polices personnalisées, un effet animé. J'espère que ça vous plaira

1
Muhammad Jobayer

Création d'une fenêtre de superposition du système (toujours au-dessus)

Cela suggère que cela peut être fait, j'ai également besoin de boutons dans un pain grillé, donc je dois toujours faire ma propre implémentation. Si j'en trouve plus, je l'ajouterai à mon message

0
Martijn de Langh

Utilisez une alerte si vous souhaitez ajouter un bouton :-). Voici quelques exemples Boîtes de dialogue sous Android

0
Martin