Notificaciones : SnackBar
Anteriormente ya vimos como podíamos mostrar un breve texto al usuario a modo de notificación utilizando un Toast. Cuando Material Design vio la luz con Android 5, lo acompañó un nuevo componente que cambiaría ‘ligeramente’ la manera en la que se muestran las notificaciones dentro de la aplicación. Este componente en cuestión es nuestro protagonista de hoy y se llama SnackBar.
Igual que con un Toast, el Snackbar nos sirve para mostrar avisos al usuario de una manera sencilla y rápida. Por ejemplo, en aplicaciones de correo, podemos ver un SnackBar al borrar un email, o al enviarlo. A diferencia del toast, podemos mostrar un texto en el SnackBar que permita realizar una acción, comúnmente esta acción es el ‘deshacer’ la operación anterior.
Pongámonos en situación :
Estamos en nuestro buzón de entrada del correo, seleccionamos un mensaje para eliminarlo. Justo cuando eliminamos el correo nos aparece un Snackbar que dice «Mensaje eliminado», a su derecha podremos observar un texto que dice «Deshacer», pulsandolo revertiremos la última acción realizada devolviendo el mensaje al buzón de entrada.
Entendiendo esto podemos ponernos manos a la obra para crear nuestro SnackBar.
Contenido:
Implementación de un SnackBar
Para este ejemplo he creado un nuevo proyecto en Android Studio utilizando como plantilla una Actividad Básica.
Al crear un proyecto nuevo veremos el Snackbar ya implementado por defecto en el MainActivity.
Si vais a escribir en un proyecto ya creado anteriormente, aseguraros que compiláis el paquete de soporte en el archivo build.gradle :
compile 'com.android.support:design:24.2.0'
Lo siguiente que haremos será añadir varios botones y un selector de RadioButton al contenido del activity principal, que nos permitan mostrar las diferentes opciones de SnackBar que podemos crear. Para ello nos dirigimos al archivo content_main.xml situado en el directorio >res>layout.
Borramos el Textview de «Hello World» que aparece por defecto, y dejamos el archivo igual a este :
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="es.mscdroidlabs.snackbarejemplo.MainActivity" tools:showIn="@layout/activity_main" android:gravity="center"> <Button android:id="@+id/btn_snack_sin_accion" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Mostrar SnackBar sin botón de acción" android:layout_centerHorizontal="true" /> <Button android:id="@+id/btn_snack_con_accion" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Mostrar SnackBar con botón de acción" android:layout_below="@id/btn_snack_sin_accion" android:layout_centerHorizontal="true"/> <Button android:id="@+id/btn_snack_con_accion_color" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Mostrar SnackBar con botón de acción de color" android:layout_below="@id/btn_snack_con_accion" android:layout_centerHorizontal="true"/> <RadioGroup android:id="@+id/radioGroup" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="20dp" android:gravity="center" android:layout_below="@+id/btn_snack_con_accion_color" android:layout_centerHorizontal="true"> <RadioButton android:id="@+id/rdo_short" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Length.Short" android:checked="true"/> <RadioButton android:id="@+id/rdo_long" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Length.Long" /> </RadioGroup> </RelativeLayout>
Este layout nos dará un aspecto como el siguiente :
Con nuestro contenido creado, pasaremos a ver la forma de instanciar el componente SnackBar.
Esculpiendo el Snackbar
Dentro del objeto encontramos el método .make() éste como mínimo necesita 3 parámetros para funcionar:
- El primero es una vista (View). Normalmente se le pasa el view que viene del evento onClick(view v), pero si no es el caso podéis pasarle directamente vuestro CordinatorLayout.
- El siguiente parámetro es un tipo String, éste será el mensaje que veremos en el SnackBar.
- El tercer y último parámetro es un entero [int|Integer] que definirá el tiempo que será visible el Snackbar. Tenemos 2 posibles opciones:
- Snackbar.LENGTH_SHORT
- Snackbar.LENGTH_LONG
La sintaxis final quedará algo así :
Snackbar.make(v, "SnackBar sin acción", Snackbar.LENGTH_SHORT) .show();
Si quisiéramos incluir una acción disponemos del método .setAction(String, OnClickListener)
- Primer parámetro | String : Es el texto que aparecera para el botón de acción
- Segundo parámetro | OnClicListener : Es el evento que se producirá una cuando pulsemos el botón.
En nuestro ejemplo la sintaxis final con acción queda así :
Snackbar.make(v, "Snackbar con acción", LENGTH.SHORT) .setAction("Cerrar app", Evento_Accion).show();
De la misma manera que añadimos una acción, también podemos cambiar el color del botón, utilizando el siguiente método:
.setActionTextColor(getResources().getColor(android.R.color.holo_green_light))
El parámetro a seleccionar es un int correspondiente a un color.
Finalmente utilizamos el método .show() para mostrar el SnackBar al usuario.
Escribiendo en el MainActivity
Hasta aquí, ya tenemos creada nuestra interfaz gráfica, sabemos como utilizar un SnackBar y como añadirle una acción.
Solo queda darle lógica a nuestra actividad para coordinar todos los elementos:
En nuestra app hemos creado 3 botones que nos permitirán mostrar SnackBars de diferentes características : sin acción, con acción y con botón de acción en otro color. Mediante un grupo de RadioButtons permitiremos seleccionar la duración de nuestro SnackBar.
public class MainActivity extends AppCompatActivity { //Instanciamos los componentes, botones y radioGroup Button snack_sin_acc; Button snack_con_acc; Button snack_con_acc_color; //Variable para almacenar el estado de los radioButtons private int tmp_checked; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); //Floating añadido por defecto al crear el nuevo proyecto, comentaremos este trozo para evitar confusiones /*FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null) .show(); } });*/ //Declaramos los botones snack_sin_acc = (Button) findViewById(R.id.btn_snack_sin_accion); snack_con_acc = (Button) findViewById(R.id.btn_snack_con_accion); snack_con_acc_color = (Button) findViewById(R.id.btn_snack_con_accion_color); //Los asociamos al evento OnClic que hemos creado más abajo snack_sin_acc.setOnClickListener(Evento_Clic); snack_con_acc.setOnClickListener(Evento_Clic); snack_con_acc_color.setOnClickListener(Evento_Clic); //Declaramos el ReadioGroup y registramos cuando se pulsa alguno de ellos mediante //el método ".setOnCheckedChangeListener" RadioGroup rdo_group = (RadioGroup) findViewById(R.id.radioGroup); rdo_group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { //Comprobamos qué elemento se ha pulsado, según cual de ellos hayamos seleccionado //asociamos el valor correspondiente a la duración del SnackBar. switch (checkedId){ case R.id.rdo_short: tmp_checked = Snackbar.LENGTH_SHORT; break; case R.id.rdo_long: tmp_checked = Snackbar.LENGTH_LONG; break; } } }); } private View.OnClickListener Evento_Clic = new View.OnClickListener() { @Override public void onClick(View v) { //Comprobamos qué botón se ha pulsado y creamos el SnackBar con las //opciones correspondientes. switch (v.getId()){ case (R.id.btn_snack_sin_accion): Snackbar.make(v, "SnackBar sin acción", tmp_checked) .show(); break; case (R.id.btn_snack_con_accion): Snackbar.make(v, "Snackbar con acción", tmp_checked) .setAction("Cerrar app", Evento_Accion).show(); break; case (R.id.btn_snack_con_accion_color): Snackbar.make(v, "Snackbar con acción y color", tmp_checked) .setAction("Cerrar app", Evento_Accion) .setActionTextColor(getResources().getColor(android.R.color.holo_green_light)) .show(); break; } } }; private View.OnClickListener Evento_Accion = new View.OnClickListener() { @Override public void onClick(View v) { //Cerramos la app finish(); } };
Y con esto finaliza esta entrada! Veis que fácil es mostrar un SnackBar?
Ya no hay ninguna excusa para seguir utilizando esos feos Toast. Si tenéis cualquier duda, podéis dejar un comentario más abajo!