Saltar la navegación

3.3. Otras ventanas

Aparte de activities y fragments, podemos utilizar los diálogos para ventanas más sencillas. Por norma general, un diálogo no ocupará toda la pantalla, sino que mostrará un mensaje al usuario con un par de botones. Podría mostrar, además, algunos controles que faciliten al usuario la introducción de datos o la elección de alguna preferencia antes de continuar otro proceso.

Podríamos crear un diálogo a partir de una activity diseñando el layout pero utilizando el tema Theme.Holo.Dialog en el manifest: <activity android:theme  = "@android:style/Theme.Holo.Dialog">.

Entonces, la actividad se mostrará en forma de diálogo en lugar de mostrarse en pantalla completa. Sin embargo, si el diseño del layout no es muy complejo, podemos utilizar las subclases de Dialog que nos proporciona el SDK, veamos algunas:

AlertDialog

Esta subclase de Dialog muestra un título y varios botones, de forma opcional. Es capaz también de mostrar una lista de elementos de los que el usuario podrá seleccionar. Veamos un ejemplo sencillo: imaginemos que necesitamos asegurarnos de que el usuario quiere borrar un elemento de nuestra app. Podemos utilizar un código como:

AlertDialog.Builder(context)
.setTitle("Borrar elemento")
.setMessage("¿Está seguro de que desea eliminar el elemento?")
.setPositiveButton(android.R.string.yes) { dialog, which ->
Log.d("Dialog", "---------------- YES ----------------")
//TODO: borrar el elemento
}
//Si utilizamos null como listener, el diálogo simplemente se cierra
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show(

Como vemos, la clase AlertDialog utiliza un patrón de diseño llamado Builder. El patrón de diseño Builder es un patrón creacional que consigue separar la construcción de un objeto complejo de su representación, de modo que el mismo proceso de construcción pueda ser responsable de crear diferentes representaciones. Crear el diálogo mediante un Builder es sencillo, pues se documenta a sí mismo:

  • setTitle y setMessage establecen el título y el mensaje que se mostrarán;
  • setPositiveButton establece el título del botón positivo y la acción que se llevará a cabo si el usuario acepta;
  • setNegativeButton establece el título y la acción si el usuario rechaza la acción;
  • setIcon muestra el icono del diálogo;
  • show mostrará el diálogo, que paraliza el código hasta que el usuario escoja una opción.

Imaginemos ahora que requerimos al usuario que elija una opción entre varias:

val colores = arrayOf("Rojo", "Verde", "Azul")
AlertDialog.Builder(context)
.setTitle("Elige un color")
.setItems(colores) { dialog, which ->
Log.d("Dialog", "Color elegido: ${colores[which]}")
}
.create()
.show()

Como vemos, el Builder nos facilita la creación de un diálogo diferente, pero siguiendo el mismo patrón que antes. Ahora utilizaremos setItems para establecer las opciones disponibles, recibiendo en la variable which cuál de las opciones eligió el usuario.

DatePickerDialog y TimePickerDialog

Estas dos subclases de Dialog han sido especialmente diseñadas para que el usuario seleccione una fecha o una hora, respectivamente. Veamos un ejemplo sencillo:

DatePickerDialog(requireContext(),
OnDateSetListener { view, year, monthOfYear, dayOfMonth ->
Log.d("Dialog", "Fecha seleccionada: $dayOfMonth/${monthOfYear+1}/$year")
}, 2022, 7, 10
)
.show()

De esta manera, mostramos al usuario un calendario con la fecha 10/08/2022 seleccionada por defecto. Atención a los meses, pues muchas funciones del SDK consideran enero como el mes 0, por lo tanto, el 7 será agosto. Cuando el usuario seleccione la fecha que desee, la obtendremos en las variables dayOfMonth, monthOfYear y year. Para la hora, sería algo similar:

TimePickerDialog(requireContext(),
OnTimeSetListener { view, hourOfDay, minute ->
Log.d("Dialog", "Hora seleccionada: $hourOfDay:$minute")
}, 12, 5, false
)
.show()

Establecemos la hora que se mostrará por defecto, las 12 horas y 5 minutos; false indica que no deseamos que se muestre en formato de 24 horas.

Cuando el usuario seleccione la hora que quiere, recibiremos los datos en hourOfDay y minute.

Creado con eXeLearning (Ventana nueva)