Estoy usando un Snackbar de la com.android.support:design:22.2.0
biblioteca. Lo estoy usando para deshacer eliminaciones. Para hacer mi vida más fácil, haré que la interfaz de usuario parezca que las cosas realmente se eliminaron de la fuente de datos, y si no se presiona el botón Deshacer en la barra de refrigerios, en realidad realizaré las eliminaciones de la fuente de datos. Entonces, quiero saber cuándo la barra de bocadillos ya no está visible, por lo que es seguro eliminar los elementos.
Puedo llamar a getView () en la Snackbar, pero no estoy seguro de qué oyente debería usar. Lo intenté setOnSystemUiVisibilityChangeListener()
pero no funcionó, creo que es solo para la barra de estado del sistema.
Además, Snackbar no se puede ampliar, ya que tiene un constructor privado.
Respuestas:
La biblioteca de diseño de Google admite devoluciones de llamada de Snackbar en la versión 23. Consulte los documentos de Snackbar y los documentos de devolución de llamada . A continuación, se le notificará cuando se cierre la barra de aperitivos (y también cuando se muestre) y también el tipo de despido si esto es útil para usted:
snackbar.addCallback(new Snackbar.Callback() { @Override public void onDismissed(Snackbar snackbar, int event) { //see Snackbar.Callback docs for event details ... } @Override public void onShown(Snackbar snackbar) { ... } });
fuente
snackbar.addCallback(new Snackbar.Callback() { @Override public void onDismissed(Snackbar snackbar, int event) { if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) { // Snackbar closed on its own } } @Override public void onShown(Snackbar snackbar) { ... } });
fuente
if (event != Snackbar.Callback.DISMISS_EVENT_ACTION)
en su lugar, de lo contrario, su lógica de descarte no se ejecutará si el usuario cierra manualmente o si un snackbar es descartado por otro snackbar consecutivo.event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT
Snackbar.addCallback en kotlin
val snackBar = Snackbar .make(view, "Text Snackbar", Snackbar.LENGTH_LONG) .addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() { override fun onShown(transientBottomBar: Snackbar?) { super.onShown(transientBottomBar) } override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { super.onDismissed(transientBottomBar, event) } }) val snackBarView = snackBar.view snackBarView.setBackgroundColor(Color.RED) snackBar.show()
fuente
Recientemente me topé con este asunto cuando, para desplazarme y mostrar Snackback, se mostraron demasiados antes de que el primero desapareciera. Tenía que encontrar una manera de saber si la aplicación debería haber establecido la barra de bocadillos.
Yo personalmente encontré esta solución.
Es cierto que Snackbar en sí no ofrece ningún tipo de oyente para su estado / visibilidad, pero aún puede obtener el objeto de visualización de Snackbar (getView ();). Desde el objeto de vista, tiene la oportunidad de utilizar una amplia variedad de métodos para agregar oyentes.
Para implementarlo, debe salirse del uso común de Toast / Snackbar "todo en una línea", porque agregar oyentes devuelve void .
Personalmente encontré OnAttachStateChangeListener para satisfacer mis necesidades.
Dejando caer un snipper con mi código en caso de que pueda resultarle útil.
Snackbar snack = Snackbar.make(getView(), "My Placeholder Text", Snackbar.LENGTH_LONG); snack.getView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) { canDisplaySnackbar = false; } @Override public void onViewDetachedFromWindow(View v) { Handler h = new Handler(); h.postDelayed(new Runnable() { @Override public void run() { canDisplaySnackbar = true; } }, 1000); } }); snack.show();
Tenga en cuenta que esta es solo mi implementación para mi propio problema, es posible que Handler con un postDelayed Runnable ni siquiera se ajuste a su caso. Fue solo para dar una idea general de la implementación que sugerí usando un fragmento que ya tengo.
fuente
Para recibir una notificación cuando se muestre o descarte un snackbar, puede proporcionar un Snackbar.Callback a través de setCallback (Callback).
fuente
onDismissed también se llama cuando se hace clic en la acción Text por ese motivo es necesario poner una condición como
event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT
Y ahora el nuevo código se ve a continuación.
final Snackbar snackBar = Snackbar.make(findViewById(R.id.root_layout), result, Snackbar.LENGTH_LONG); snackbar.addCallback(new Snackbar.Callback() { @Override public void onDismissed(Snackbar snackbar, int event) { if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) { // Snackbar closed on its own } } @Override public void onShown(Snackbar snackbar) { ... } }); snackBar.show();
fuente
if (event != Snackbar.Callback.DISMISS_EVENT_ACTION)
en su lugar, de lo contrario, su lógica de descarte no se ejecutará si el usuario cierra manualmente o si un snackbar es descartado por otro snackbar consecutivo.setCallback
ahora está en desuso yaddCallback
debería usarsehttps://developer.android.com/reference/android/support/design/widget/BaseTransientBottomBar.html#addCallback(android.support.design.widget.BaseTransientBottomBar.BaseCallback )
fuente
Actualmente no hay forma de recibir una notificación cuando la barra de aperitivos haya terminado de mostrarse.
En este hilo se analiza una solución alternativa basada en un temporizador para la duración de la visualización de Snackbar. ¿Snackbar en la biblioteca de soporte no incluye OnDismissListener ()?
Un problema a considerar con esta solución alternativa es que es posible que se reinicie la duración de Snackbar. La especificación de diseño de material para Snackbar dice que esto sucederá si se muestra un cuadro de diálogo o ventana emergente no relacionado.
fuente
Actualmente no puedes lograrlo.
No se llama a un oyente cuando el snackbar está atenuado.
La forma más sencilla de hacerlo es guardar temporalmente el registro en otro lugar (incluso una variable local) y luego volver a insertarlo si presionan el botón Deshacer.
fuente
snackbar.addCallback(new Snackbar.Callback() { public void onShown(Snackbar snackbar) { // on show } public void onDismissed(Snackbar snackbar, int event) { // on dismiss } });
fuente
Tengo exactamente el mismo problema que el tuyo. Mi solución es ...
final Snackbar povrati_obrisani_unos = Snackbar.make (coordinatorLayout, "Ponisti brisanje", Snackbar.LENGTH_INDEFINITE) .addCallback (new Snackbar.Callback (){ @Override public void onDismissed(Snackbar transientBottomBar, int event) { super.onDismissed (transientBottomBar, event); if(event==DISMISS_EVENT_SWIPE){//here we detect if snackbar is swipped away and not cliked (which is undo in my case) Uri uriDelete = Uri.parse (obrisano.getImageuri ()); ContentResolver contentResolver = getContentResolver(); contentResolver.delete (uriDelete, null, null); Toast.makeText (MainActivity.this, "Ocitavanje i slika su trajno obrisani", Toast.LENGTH_SHORT).show (); }
Eso es todo, no quiero copiar y pegar snackbar.action que es deshacer. Quiero ser lo más claro posible aquí.
Saludos Nenad
fuente
Gracias a @SergeyMilakov en Kotlin es:
@SuppressLint("WrongConstant") // Suppress an error when set duration. private fun showSnackbar() { val DURATION = 5000 Snackbar.make(view!!, "Remove item?"), DURATION).apply { setAction("Undo") { // Your action when a button is clicked. } addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() { /* override fun onShown(transientBottomBar: Snackbar?) { super.onShown(transientBottomBar) Timber.d("*** onShown") }*/ override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { super.onDismissed(transientBottomBar, event) if (event != Snackbar.Callback.DISMISS_EVENT_ACTION) { // Your action when the Snackbar is closed and the button was not clicked. } } }) view.setBackgroundColor(ContextCompat.getColor(context, R.color.black)) setActionTextColor(ContextCompat.getColor(context, R.color.yellow)) show() } }
Tenga en cuenta que se
Snackbar
muestra, incluso si se mueve a otras pantallas (por ejemplo, hacia atrás). Por lo tanto, no olvide verificar si realiza acciones en la pantalla correcta.Tampoco
Snackbar
se restaura después de la rotación de la pantalla.fuente