tipos - Botón en Android Toast personalizada?
java toast message (8)
¿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?
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
.
- Descargue
Android Support Library
deExtras
enSDK Manager
(revisión 22.2.1 o posterior). - En
build.gradle
agregue esto a las dependencias de clase:com.android.support:design:22.2.0
. 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.
El fragmento muestra la implementación de toast personalizado que:
- 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
enmillis
- 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
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.
Puedes probar SuperToasts en este caso. Puede crear brindis con el botón. Tiene una función de duración personalizada, fondo colorido, fuentes coloridas, fuentes personalizadas, efecto animado. Espero que lo disfrutes
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.
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 SuperToasts sin embargo, podría ser un poco exagerado para un solo uso. La forma en que lo hago se describe en la clase SuperActivityToast .
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