Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK
Code

Mostrando cuadros de diálogo con Material Design en una aplicación Android

by
Difficulty:BeginnerLength:LongLanguages:

Spanish (Español) translation by Ana Paulina Figueroa Vazquez (you can also view the original English article)

El equipo de material design en Google define la funcionalidad de los cuadros de diálogo en Android de la siguiente manera:

Los cuadros de diálogo informan a los usuarios acerca de una tarea específica y pueden contener información crítica, requerir decisiones o involucrar múltiples tareas.

Ahora que has entendido para qué se usan los cuadros de diálogo, es momento de aprender a mostrarlos. En este tutorial te guiaré a través del proceso de despliegue de diferentes tipos de cuadros de diálogo con material design en Android. Vamos a cubrir los siguientes cuadros de diálogo:

  • alerta
  • elección simple y múltiple
  • selector de fecha y hora
  • cuadro de diálogo de hoja inferior
  • cuadro de diálogo de pantalla completa

Puedes encontrar un proyecto de ejemplo para este tutorial en nuestro repositorio de GitHub para que puedas seguirlo fácilmente.

1. Cuadro de diálogo de alerta

De acuerdo a la documentación oficial de material design de Google:

Las alertas son interrupciones urgentes, que requieren respuesta y que informan al usuario acerca de una situación.

Creando un cuadro de diálogo de alerta

Asegúrate de incluir el artefacto appcompat más reciente en tu archivo build.gradle (módulo app). El nivel API mínimo compatible es Android 4.0 (API nivel 14).

Lo siguiente es crear una instancia de AlertDialog.Builder.

Aquí creamos una instancia de AlertDialog.Builder y comenzamos a configurar la instancia invocando algunos métodos setter en ella. Toma en cuenta que estamos usando el AlertDialog del artefacto de soporte de Android.

Aquí están los detalles de los métodos setter que invocamos en la instancia de AlertDialog.Builder.

  • setTitle(): establece el texto a mostrar en la barra de título del cuadro de diálogo.
  • setMessage(): establece el mensaje a mostrar en el cuadro de diálogo.
  • setPositiveButton(): el primer argumento proporcionado es el texto a mostrar en el botón afirmativo, mientras que el segundo argumento es el manejador invocado cuando se hace clic en el botón afirmativo.
  • setNegativeButton(): el primer argumento proporcionado es el texto a mostrar en el botón negativo, mientras que el segundo argumento es el manejador invocado al hacer clic en el botón negativo.

Toma en cuenta que el AlertDialog.Builder tiene un setView() para establecer la vista de tu diseño personalizado en él.

Para mostrar nuestro cuadro de diálogo en la pantalla solamente hay que ejecutar la función show().

Alert dialog

Hay otro método setter llamado setNeutralButton(). Si invocamos a este método se agregará otro botón del lado izquierdo del cuadro de diálogo. Para llamar a este método tenemos que enviar un valor String que servirá como texto para el botón, y también un manejador que será invocado cuando se pulse sobre el botón.

Alert dialog with neutral button

Toma en cuenta que si pulsas fuera del cuadro de diálogo, éste será ignorado automáticamente. Para evitar que esto ocurra tendrás que invocar al método setCanceledOnTouchOutside() de la instancia AlertDIalog y enviar el valor false como argumento.

Para evitar que el cuadro de diálogo sea descartado presionando el botón BACK (Atrás), entonces tienes que invocar al método setCancelable() en la instancia de AlertDialog y enviar el valor false como argumento.

Añadiendo estilo a un cuadro de diálogo de alerta

Es bastante sencillo darle un estilo a nuestro cuadro de diálogo. Solamente debemos crear un estilo personalizado en el recurso styles.xml. Observa que el padre de este estilo es Theme.AppCompat.Light.Dialog.Alert. En otras palabra, este estilo hereda algunos atributos de estilo de su padre.

Comenzamos a personalizar el estilo del cuadro de diálogo configurando los valores de los atributos que serán aplicados al cuadro de diálogo, por ejemplo, podemos cambiar el color de su botón para que sea @android:color/holo_orange_dark y también establecer el color de fondo del cuadro para que sea un recurso drawable personalizado de nuestra carpeta de recursos drawable (android:windowBackground con el valor @drawable/background_dialog asignado).

Aquí está mi archivo de recursos background_dialog.xml.

Aquí creamos un InsetDrawable personalizado, que nos permite añadir grabados en cualquier lado del ShapeDrawable. Creamos un rectángulo usando la etiqueta <shape>. Establecemos el valor del atributo android:shape de la etiqueta <shape> para que sea de tipo rectangle (otros valores posibles son line (línea), oval (óvalo), ring (anillo)). Tenemos una etiqueta hija <corners> que establece el radio de las esquinas del rectángulo. Para un relleno sólido agregamos la etiqueta <solid> con un atributo android:color que indica el color que se debe usar. Finalmente le damos un borde a nuestro drawable usando la etiqueta <stroke> en <shape>.

Para aplicar este estilo al cuadro de diálogo, solamente tenemos que enviar el estilo personalizar al segundo parámetro del constructor de AlertDialog.Builder.

Alert dialog with custom style

2. Cuadros de diálogo de confirmación

De acuerdo a la documentación de material design:

Los cuadros de diálogo de confirmación requieren que los usuarios confirmen explícitamente su elección antes de que se lleve a cabo una opción. Por ejemplo, los usuarios pueden escuchar múltiples timbres pero solamente hacen la selección final al pulsar en "OK".

Los siguientes tipos diferentes de cuadros de diálogo de confirmación están disponibles:

  • cuadro de diálogo de elección múltiple
  • cuadro de diálogo de elección simple
  • selector de fechas
  • selector de horas

Cuadro de diálogo de elección múltiple

Utilizamos un cuadro de diálogo de elección múltiple cuando queremos que el usuario seleccione más de un elemento en un cuadro de diálogo. En un cuadro de este tipo aparece una lista de opciones para que el usuario elija de entre ellas.

Para crear un cuadro de diálogo de elección múltiple, simplemente invocamos al método setter setMultiChoiceItems() en la instancia AlertDialog.Builder. Dentro de este método enviamos un Array de tipo String como primer parámetro. Este es mi arreglo, localizado en el archivo de recursos de tipo arreglo /values/arrays.xml.

El segundo parámetro para el método setMultiChoiceItems() acepta un arreglo que contiene los elementos que están marcados. El valor de cada elemento del arreglo checkedItems corresponde a cada valor en el arreglo multiChoiceItems. Usamos nuestro arreglo checkedItems (cuyos valores son false de forma predeterminada) para hacer que todos los elementos estén desmarcados de forma preestablecida. En otras palabras, el primer elemento "Dark Knight" está desmarcado debido a que el primer elemento del arreglo checkedItems es false, y así sucesivamente. Si el primer elemento del arreglo checkedItems tuviera el valor true, entonces "Dark Knight" estaría marcado.

Toma en cuenta que este arreglo checkedItems se actualiza cuando seleccionamos o hacemos clic en cualquier elemento mostrado, por ejemplo, si el usuario seleccionara "The Shawshank Redemption", la llamada a checkedItems[1] devolvería el valor true.

El último parámetro acepta una instancia de OnMultiChoiceClickListener. Aquí simplemente creamos una clase anónima y sobrescribimos onClick(). Obtenemos una instancia del cuadro de diálogo mostrado en el primer parámetro. En el segundo parámetro obtenemos el índice del elemento que fue seleccionado. Finalmente, en el último parámetro descubrimos si el elemento seleccionado fue marcado o no.

Multichoice dialog

Cuadro de diálogo de elección simple

En un cuadro de diálogo de elección simple, a diferencia del de elección múltiple, solamente se puede seleccionar un elemento.

Para crear un cuadro de diálogo de elección simple, sencillamente invocamos al setter setSingleChoiceItems() en la instancia de AlertDialog.Builder. Dentro de este método también enviamos un Array de tipo String como primer parámetro. Este es el arreglo que enviamos, que se localiza en el archivo de recursos de tipo arreglo: /values/arrays.xml.

El segundo parámetro de setSingleChoiceItems() se usa para determinar qué elemento está marcado. El último parámetro en onClick() nos proporciona el índice del elemento que fue seleccionado, por ejemplo, si se elige el elemento Female, el valor de selectedIndex será 1.

Single choice dialog

Cuadro de diálogo selector de fechas

Este es un cuadro de diálogo selector que se usa para elegir una fecha única.

Para comenzar, crearemos una instancia de un campo Calendar en MainActivity y la inicializaremos.

Aquí invocamos a Calendar.getInstance() para obtener la hora actual (en la zona horaria predeterminada) y asignamos ese valor al campo mCalendar.

Para mostrar un cuadro de diálogo selector de fechas, creamos una instancia de DatePickerDialog. Aquí está la explicación de las definiciones de parámetros al crear una instancia de este tipo.

  • El primer parámetro acepta un contexto de tipo padre, por ejemplo, en una Activity usas this, mientras que en un Fragment invocas al método getActivity().
  • El segundo parámetro acepta un manejador de tipo OnDateSetListener. Este manejador onDataSet() es invocado cuando el usuario selecciona la fecha. Dentro de este método, obtenemos el año seleccionado, el mes del año seleccionado y también el día del mes seleccionado.
  • El tercer parámetro es el año seleccionado inicialmente.
  • El cuarto parámetro es el mes seleccionado inicialmente (0-11).
  • El último parámetro es el día del mes seleccionado incialmente (1-31).

Finalmente, invocamos al método show() de la instancia de DatePickerDialog para mostrarlo en la pantalla actual.

Date picker dialog

Estableciendo un tema personalizado

Es muy sencillo personalizar el tema del cuadro de diálogo selector de fechas (similar a lo que hicimos en el cuadro de diálogo de alerta).

Brevemente, puedes crear un drawable personalizado, crear un estilo o un tema personalizado, y luego aplicar dicho tema al crear una instancia de DatePickerDialog en el segundo parámetro.

Cuadro de diálogo selector de horas

El cuadro de diálogo selector de horas permite al usuario elegir una hora y se ajusta a la configuración horaria preferida por el usuario, es decir, el formato de 12 horas o el de 24.

Como puedes ver en el siguiente código, la creación de un TimePickerDialog es muy similar a la creación de un DatePickerDialog. Al crear una instancia del TimePickerDialog enviamos los siguientes parámetros:

  • El primer parámetro acepta un contexto de tipo padre.
  • El segundo parámetro acepta una instancia de OnTimeSetListener que sirve como manejador.
  • El tercer parámetro es la hora inicial del día.
  • El cuarto parámetro es el minuto inicial.
  • El último parámetro es para indicar si queremos la vista en formato de 24 horas o en el de AM/PM.

El método onTimeSet() se invoca cada vez que el usuario haya seleccionado la hora. Dentro de este método obtenemos una instancia del TimePicker, la hora seleccionada del día elegido, además del minuto seleccionado.

Para mostrar este cuadro de diálogo aún tenemos que ejecutar el método show().

Time picker dialog

El selector de hora puede estilizarse de manera similar a como se hace para el cuadro de diálogo selector de fechas.

3. Cuadro de diálogo de hoja inferior

De acuerdo a la documentación oficial de material design de Google:

Las hojas inferiores se deslizan hacia arriba desde la parte inferior de la pantalla para revelar más contenido.

Para comenzar a usar el cuadro de diálogo de hoja inferior, tienes que importar el artefacto de soporte de design, así que visita el archivo build.gradle de tu módulo app para importarlo.

Asegúrate de que la activity o el fragment para el cuadro de diálogo de hoja inferior aparezca. Su diseño padre es el CoordinatorLayout.

Aquí también tenemos un FrameLayout que servirá como contenedor para nuestra hoja inferior. Observa que uno de los atributos de este FrameLayout es app:layout_behavior, cuyo valor es un recurso especial de tipo cadena que apunta a android.support.design.widget.BottomSheetBehavior. Esto permitirá que nuestro FrameLayout aparezca como una hoja inferior. Toma en cuenta que, si no incluyes este atributo, tu aplicación dejará de funcionar.

Aquí declaramos una instancia de BottomSheetDialog como un campo para nuestro MainActivity.java y la inicializamos en el método onCreate() de nuestra activity.

En el código anterior inflamos nuestro diseño de hoja inferior R.layout.bottom_sheet_dialog. Configuramos manejadores para los botones Cancel (Cancelar) y Ok en el archivo bottom_sheet_dialog.xml. Al hacer clic en el botón Cancel simplemente ignoramos el cuadro de diálogo.

Después inicializaamos nuestro campo mBottomSheetDialog y asignamos la vista usando setContentView(). Finalmente, invocamos al método show() para mostrarlo en la pantalla.

Este es mi archivo bottom_sheet_dialog.xml:

Bottom sheet dialog

Asegúrate de consultar Cómo usar Hojas Inferiores con la Biblioteca de Soporte de Design de Paul Trebilcox-Ruiz aquí en Envato Tuts+ para aprender más acerca de las hojas inferiores.

4. Diálogo de pantalla completa

De acuerdo a la documentación oficial de material design de Google:

Los diálogos de pantalla completa agrupan una serie de tareas (por ejemplo la creación de una entrada en el calendario) antes de que sean ejecutadas o descartadas. No se guarda ninguna selección hasta pulsar el botón "Save" ("Guardar"). Al pulsar la "X" se descartan todos los cambios y se cierra el cuadro de diálogo.

Ahora veamos cómo crear un cuadro de diálogo de pantalla completa. Primero, asegúrate de incluir el artefacto de soporte v4 de Android en el módulo build.gradle de tu aplicación. Esto es necesario para la compatibilidad con Android 4.0 (API nivel 14) y versiones más recientes.

A continuación crearemos un FullscreenDialogFragment que extienda a la superclase DialogFragment.

Aquí sobrescribimos el método onCreateView() (al igual que como lo haríamos con un Fragment ordinario). Dentro de este método, simplemente inflamos y devolvemos el diseño (R.layout.full_screen_dialog)  que servirá como una vista personalizada para el cuadro de diálogo. Configuramos un OnClickListener en ImageButton (R.id.button_close) que descartará el cuadro de diálogo cuando se haga clic sobre él.

También sobrescribimos onCreateDialog() y devolvemos un Dialog. Dentro de este método también puedes devolver un AlertDialog creado usando un AlertDialog.Builder.

Nuestro R.layout.full_screen_dialog está compuesto por un ImageButton, un Button y algunas etiquetas TextView:

En el widget ImageButton verás un atributo app:srcCompat que hace referencia a un VectorDrawable (@drawable/ic_close) personalizado. Este VectorDrawable personalizado crea el botón X, que cierra el cuadro de diálogo de pantalla completa al pulsar sobre él.

Para usar este atributo app:srcCompat asegúrate de incluirlo en tu archivo build.gradle. A continuación configura tu aplicación para que use bibliotecas de soporte de vectores y agrega el elemento vectorDrawables a tu archivo build.gradle en el módulo app.

Hicimos esto para lograr la compatibilidad con todas las versiones de la plataforma Android, incluyendo a Android 2.1 (API nivel 7+).

Finalmente, para mostrar el FullscreenDialogFragment simplemente usamos el FragmentTransaction para añadir nuestro fragmento a la IU.

Full screen dialog

5. Sobreviviendo a la orientación del dispositivo

Toma en cuenta que todos los cuadros de diálogo mostrados aquí, con excepción del cuadro de pantalla completa, serán descartados automáticamente cuando el usuario cambie la orientación de la pantalla del dispositivo Android, de vertical a horizontal (o viceversa). Esto se debe a que el sistema Android ha destruido y creado de nuevo la Activity para adaptarla a la nueva orientación.

Para que podamos conservar el cuadro de diálogo a través de los cambios de orientación de la pantalla, tendremos que crear un Fragment que extienda a la superclase DialogFragment (al igual que como lo hicismo para el ejemplo del cuadro de diálogo de pantalla completa).

Veamos un ejemplo sencillo con un cuadro de diálogo de alerta.

Aquí creamos una clase que extiende a DialogFragment y que también implementa al DialogInterface.OnClickListener. Ya que implementamos este manejador, ahora tenemos que sobrescribir el método onClick(). Toma en cuenta que si pulsamos el botón afirmativo o el de negación, este método onClick() será ejecutado.

Dentro de nuestro onCreateDialog() creamos y devolvemos una instancia de AlertDialog.

Tambien hemos sobrescrito:

  • onCancel(): este método se invoca si el usuario presiona el botón BACK (Atrás) para cerrar el cuadro de diálogo.
  • onDismiss(): este se invoca cada vez que el cuadro de diálogo sea forzado a acerrarse por cualquier razón (BACK o la pulsación de un botón).

Para mostrar este cuadro de diálogo, simplemente invocamos al método show() en una instancia de nuestro AlertDialogFragment.

El primer parámetro es una instancia de FragmentManager. El segundo parámetro es una etiqueta que puede usarse para obtener este fragmento de nuevo más adelante a partir del FragmentManager y a través de findFragmentByTag().

Alert dialog on rotation

Ahora, si cambias la orientación del dispositivo de vertical a horizontal (o viceversa) el cuadro de diálogo no será descartado.

Puedes seguir pasos similares para los otros tipos de cuadros de diálogo y mantenerlos durante la rotación del dispositivo. Simplemente debes crear un Fragment que extienda a la superclase DialogFragment, y generas y devuelves el cuadro de diálogo particular en onCreateDialog().

Cuadro de diálogo de progreso (obsoleto)

Algunos de ustedes quizá hayan escuchado acerca del ProgressDialog. Este simplemente muestra un cuadro de diálogo con un indicador de progreso en él. No lo incluí aquí, ya que ProgressDialog ha sido descartado en la API nivel 26, ya que puede ocasionar una mala experiencia para tus usuarios. De acuerdo a la documentación oficial:

ProgressDialog es un diálogo modal, lo que evita que el usuario interactúe con la aplicación. En vez de usar esta clase, debes usar un indicador de progreso como ProgressBar, que puede ser incrustado en la IU de tu aplicación. De forma alternativa, puedes usar una notificación para informar al usuario sobre el progreso de la tarea.

Conclusión

En este tutorial aprendiste sobre las diferentes maneras en las que se pueden mostrar cuadros de diálogo con material design en una aplicación Android. Cubrimos los siguientes tipos de cuadros de diálogo de material design:

  • alertas
  • cuadros de diálogo de elección simple y múltiple
  • selectores de fecha y hora
  • cuadro de diálogo de hoja inferior
  • cuadro de diálogo de pantalla completa

También aprendiste cómo crear un estilo personalizado para un cuadro de diálogo y cómo lograr que tu cuadro de diálogo sobreviva a los cambios de configuración de orientación entre los modos horizontal y vertical usando DialogFragment.

Es muy recomendable que consultes las directrices oficiales para los cuadros de diálogo de material design para aprender a diseñar y usar cuadros de diálogo correctamente en Android.

Para aprender más sobre la codificación para Android, ¡revisa algunos de nuestros otros cursos y tutoriales aquí en Envato Tuts+!.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.