Botón en Android Toast personalizada?

¿Es posible tener un botón en una tostada?

En teoría, sí, porque puedes crear un Toast personalizado a partir de un diseño en XML, pero traté de ponerle un botón y no pude conseguir que registrara el clic. ¿Alguien logró hacer algo como eso?

No se puede hacer clic en una tostada. No es posible capturar un clic dentro de un mensaje de brindis. Necesitarás construir un diálogo para eso. Mire Crear Diálogos para más información.

La API en la clase Toast indica que un brindis nunca recibirá el foco y porque un brindis no es una vista, no hay un mensaje onClick. Supongo que, por lo tanto, no se puede hacer clic en los hijos de un Toast.

Una tostada no puede contener un botón. Excepto que la aplicación de Gmail y la aplicación de galería en caramelos de goma tienen una tostada que contiene un botón, así es como Google lo hizo

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

Supongo que esto responde tu pregunta.

El fragmento muestra la implementación de toast personalizado que:

Encabezamiento

  • Tener una interfaz similar a la clase Toast original
  • Se puede usar como Dialog (tiene botones que se pueden hacer clic, como la aplicación de Gmail)
  • Tiene la posibilidad de establecer la length en millis
  • Tener la posibilidad de configurar y cancelar la animación
  • Vive solo con Activity inicializada

Limitaciones actuales:

  • No se admiten cambios en la orientación de la pantalla

Uso:

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

Fuentes

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

Mi publicación original en github
Publicación que muestra la implementación del diseño personalizado en esta publicación

Una vista personalizada pasada a un brindis puede contener cualquier cosa; sin embargo, las tostadas no pueden recibir eventos táctiles, por lo que ningún componente que use eventos táctiles funcionará en un brindis estándar (botones, botones de radio, etc.). La única opción que tiene es crear una vista personalizada con un botón y agregarla a su diseño. Hay muchos ejemplos de cómo hacerlo y algunas bibliotecas que puede consultar para ver cómo lo están haciendo otras personas.

UndoBar
MessageBar
Nurik’s UndoBar

Por supuesto, también es bienvenido el uso de la biblioteca SuperToasts que reuní, sin embargo, podría ser un poco exagerado para un solo uso. La forma en que lo hago se describe en la clase SuperActivityToast .

Puedes probar SuperToast en este caso. Puede crear brindis con el botón. Tiene una función de duración personalizada, fondo colorido, fonts coloridas, fonts personalizadas, efecto animado. Espero que lo disfrutes

Use un cuadro de alerta, si desea agregar un botón :-). Aquí hay algunos ejemplos de cuadros de diálogo en Android

Crear una ventana de superposición del sistema (siempre en la parte superior)

Esto sugiere que se puede hacer, también necesito botones en un brindis así que todavía tengo que hacer mi propia implementación. Si encuentro más lo agregaré a mi publicación

Deberías usar una Snackbar . Está en la última biblioteca de soporte de Android (en el momento de la respuesta) y es compatible con niveles de API más antiguos. Es mucho más fácil de implementar que un Dialog o una View personalizada y tiene la capacidad de tener un botón a diferencia de un Toast .

  1. Descargue Android Support Library de Extras en SDK Manager (revisión 22.2.1 o posterior).
  2. En build.gradle agregue esto a las dependencias de clase: com.android.support:design:22.2.0 .
  3. Implementar:

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

Y eso es todo. Ningún proyecto e implementación de github es muy similar a Toast . Lo usé en uno de mis proyectos y funciona muy bien.