Actualizado: Mayo 2020
Tras hablar de varios de los controles indispensables en cualquier aplicación Android, como son los botones y los cuadros de texto, en este artículo vamos a ver cómo utilizar otros dos tipos de controles básicos en muchas aplicaciones, los checkboxes y los radio buttons.
Control CheckBox [API]
Un control checkbox se suele utilizar para marcar o desmarcar opciones en una aplicación, y en Android está representado por la clase del mismo nombre, CheckBox
. La forma de definirlo en nuestra interfaz y los métodos disponibles para manipularlos desde nuestro código son análogos a los ya comentados para el control ToggleButton
.
De esta forma, para definir un control de este tipo en nuestro layout podemos utilizar el código siguiente, que define un checkbox con el texto «Márcame»:
<CheckBox android:id="@+id/chkMarcame" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/marcame" android:checked="false" />
En cuanto a la personalización del control podemos decir que éste extiende [indirectamente] del control TextView
, por lo que todas las opciones de formato ya comentadas en artículos anteriores son válidas también para este control. Además, podremos utilizar la propiedad android:checked
para inicializar el estado del control a marcado (true
) o desmarcado (false
). Si no establecemos esta propiedad el control aparecerá por defecto en estado desmarcado.
En el código de la aplicación podremos hacer uso de la propiedad isChecked
para conocer el estado del control y/o asignarle un estado concreto.
En cuanto a los posibles eventos que puede lanzar este control, onClick vuelve a ser el más interesante ya que nos indicará cuándo se ha pulsado sobre el checkbox. Dentro de este evento consultaremos normalmente el estado del control con isChecked
como acabamos de ver.
chkMarcame = findViewById(R.id.chkMarcame) chkMarcame.setOnClickListener { if (it is CheckBox) { if (it.isChecked) chkMarcame.text = "Checkbox marcado!" else chkMarcame.text = "Checkbox desmarcado!" } }
Otro evento que podríamos utilizar es onCheckedChanged, que nos informa de que ha cambiado el estado del control. Para implementar las acciones de este evento podríamos utilizar la siguiente lógica, donde tras capturar el evento, y dependiendo del nuevo estado del control (variable isChecked
recibida como parámetro), haremos una acción u otra:
chkMarcame.setOnCheckedChangeListener { _, isChecked -> if (isChecked) chkMarcame.text = "Checkbox marcado!" else chkMarcame.text = "Checkbox desmarcado!" }
Control RadioButton [API]
Al igual que los controles checkbox, un radio button puede estar marcado o desmarcado, pero en este caso suelen utilizarse dentro de un grupo de opciones donde una, y sólo una, de ellas debe estar marcada obligatoriamente, es decir, que si se marca una de las opciones se desmarcará automáticamente la que estuviera activa anteriormente. En Android, un grupo de botones radio button se define mediante un elemento RadioGroup
, que a su vez contendrá todos los elementos RadioButton
necesarios. Veamos un ejemplo de cómo definir un grupo de dos controles radiobutton en nuestra interfaz:
<RadioGroup android:id="@+id/grbGrupo1" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <RadioButton android:id="@+id/rbOpcion1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/opcion_1" /> <RadioButton android:id="@+id/rbOpcion2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/opcion_2" /> </RadioGroup>
En primer lugar vemos cómo podemos definir el grupo de controles indicando su orientación (vertical u horizontal) al igual que ocurría por ejemplo con un LinearLayout
. Tras esto, se añaden todos los objetos RadioButton
necesarios indicando su ID mediante la propiedad android:id
y su texto mediante android:text
.
Una vez definida la interfaz podremos manipular el control desde nuestro código java haciendo uso de los diferentes métodos del control RadioGroup
, los más importantes: check(id)
para marcar una opción determinada mediante su ID, clearCheck()
para desmarcar todas las opciones, y getCheckedRadioButtonId()
que como su nombre indica devolverá el ID de la opción marcada (o el valor -1 si no hay ninguna marcada). Veamos un ejemplo:
grbGrupo1 = findViewById(R.id.grbGrupo1) grbGrupo1.clearCheck() grbGrupo1.check(R.id.rbOpcion1) val idSeleccionado = grbGrupo1.checkedRadioButtonId
En cuanto a los eventos lanzados, recurriremos nuevamente al evento onClick para saber cuándo se pulsa cada uno de los botones del grupo. Normalmente utilizaremos un mismo listener para todos los radiobutton del grupo, por lo que lo definiremos de forma independiente y después lo asignaremos a todos los botones.
lblMensaje = findViewById(R.id.lblMensaje) option1 = findViewById(R.id.rbOpcion1) option2 = findViewById(R.id.rbOpcion2) val handler = View.OnClickListener { view -> if (view is RadioButton) { var opcion = "" when (view.getId()) { R.id.rbOpcion1 -> opcion = "opción 1" R.id.rbOpcion2 -> opcion = "opción 2" } lblMensaje.text = "Opción seleccionada: $opcion" } } option1.setOnClickListener(handler) option2.setOnClickListener(handler)
Al igual que en el caso de los checkboxes, también podremos utilizar el evento onCheckedChange, que nos informará de los cambios en el elemento seleccionado dentro de un grupo. La diferencia aquí es que este evento está asociado al RadioGroup
, y no a los diferentes RadioButton
del grupo. Veamos cómo tratar este evento haciendo por ejemplo que una etiqueta de texto cambie de valor al seleccionar cada opción:
grbGrupo1 = findViewById(R.id.grbGrupo1) grbGrupo1.setOnCheckedChangeListener { _, checkedId -> var opcion = "" when (checkedId) { R.id.rbOpcion1 -> opcion = "opción 1" R.id.rbOpcion2 -> opcion = "opción 2" } lblMensaje.text = "Opción seleccionada: $opcion" }
Veamos finalmente una imagen del aspecto de estos dos nuevos tipos de controles básicos que hemos comentado en este artículo:
CÓDIGO DEL ARTÍCULO: Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la pagina del curso en GitHub.
23 comentarios
[…] Interfaz de usuario en Android: Controles básicos (III) […]
Gracias por el tutorial, lo estoy siguiendo y me ayuda mucho. Sigue así.
Hola,,queria saber si me podrias ayudar,, hay alguna forma de enviar un SMS sin necesidad de presionar el boton enviarSMS utilizando los datos de alguna base de datos,,, saludos coordiales,, ojala y me puedas ayudar
Has conseguido un tutorial fantástico. Me está sirviendo muchísimo, enhorabuena y muchas gracias!
Hola, me gustan tus tutoriales, sólo que a veces muestras código que luego no explicas, espero que continues con ellos, gracias!.
Hola, estas haciendo un tutorial estupendo, pero podrías explicar cuando gastas lo de «lblMensaje.setText(…);» ?
hola! me encanta tu curso, pero ojala pudieras explicar como podriamos hacer los radio button desde java,, gracias y felicitaciones =)
[…] sgoliver Móviles, Programación 2010-09-07 Una vez repasados los controles básicos (I, II, III) que podemos utilizar en nuestras aplicaciones Android, vamos a dedicar los próximos artículos a […]
Lo primero, agradecerte enormemente el curro que te pegas con el curso, es realmente bueno y de mucha utilidad.
Tengo una duda respecto a los Checkbox buttons. Me gusta declarar en los XML el parámetro android:onClick para los botones y luego en el código crear un método público con el mismo nombre. Me resulta mucho más cómodo y legible de esta forma que no con los .setOnClickListener y demás.
El problema es que no sé si puedo hacerlo con los Checkbox. Tienen el atributo :onClick, pero no me funcionan a la hora de ser pulsados. Mi código para el método onClick es este:
public void botonFavoritoPulsado (View v) {
if (btnFav.isChecked()) {
// Hacer algo
} else {
// Hacer otra cosa
}
}
La idea es la típica, si al pulsar el Checkbox, este ya estaba marcado, hacer tal cosa. Si no estaba marcado, hacer tal otra. Doy por hecho que no tengo que implementar el .setChecked(true) en este momento, ya que eso lo hace de forma automática al ser pulsado, ¿no?
Espero haberme explicado bien…
Un saludo y muchísimas gracias de nuevo.
Vale, me respondo a mí mismo. Sí que se puede hacer de esa forma, pero el código debería ir «al revés». Me explico…
Al pulsar el botón, SE MARCA el Checkbox y se ejecuta el método botonFavoritoPulsado. Por tanto, lo que había puesto en el else irá en el if y viceversa, ya que la comprobación la hace tras haberse marcado/desmarcado el Checkbox al haber sido pulsado.
Aún así, me ha surgido otro problema. Mi aplicación es un cliente Twitter que, cuando pulso sobre un tweet, me lanza otra activity que me muestra el tweet con más detalles y los correspondientes botones para responder, retwittear, marcar/desmarcar como favorito (el Checkbox en cuestión), etcétera.
Ya he conseguido que al marcar el Checkbox se marque como favorito el tweet en Twitter y que al desmarcar se borre el favorito. Mi problema es que cuando pulso la tecla BACK del teléfono y se finaliza la activity (siempre he tenido entendido que es lo que pasa al pulsar ese botón, ¿no?), vuelvo al timeline. Pero si vuelvo a pulsar sobre el tweet, al cargarme la activity del tweet en detalle, el Checkbox no está «actualizado», sigue apareciendo en el mismo estado que estaba en un principio. ¿Por qué pasa esto? Si en Twitter aparece bien el cambio y al cargar de nuevo la activity compruebo si está favoriteado para marcar el Checkbox…
Saludos y gracias de nuevo.
Excelente tuto bro, solo que e detectado un pequeño error, en la parte del radioGroup, debería ir de la siguiente manera
…
De acuerdo a la documentación de Android, no es necesario poder una id al grupo y haz tenido un error al repetir «fill_parent», con el cual, deja de ser utilizables los controles que queden debajo del RadioGroup
=) sáludos, y un agradecimiento por el tuto :D
El tutorial es realmente excelente; muy claro, sencillo y bien estructurado. De primera.
Hola que tal..
tengo una duda en esta parte
if (checkBox.isChecked()) {
checkBox.setChecked(false);
}
en que parte del codigo va? .. es un metodo? o va dentro del onCreate?
Muchisimas gracias, me estas ayudando mucho. Pero seria de mucha ayuda que facilitaras los import que usas para cada cosa.
Un saludo.
Hola Perico,
al final de cada artículo tienes un enlace directo al código completo del ejemplo en GitHub, que puedes consultar online o descargar. Saludos.
Hola tengo una duda que es lo que no voy entendiendo de esto, cuando tu pones cbMarcame.setOnCheckedChangeListener(
new CheckBox.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked)
que significa (CompoundButton buttonView, boolean isChecked)?nose si me explico,esque yo segun voy leyendo el codigo voy traduciendo el codigo pero esa parte nose que sifnifica y me pierdo. Tambien me ocurre en el radiogroup. Si me pudieras ayudar a comprender eso te lo agradeceria mucho.
Bueno el tutorial!
[…] Controles básicos (III): Checkbox y Radiobutton [v3] [Actualizado] […]
No sirve, en el android studio me sale error, no reconoce las etiquetas de
cbMarcame.setOnClickListener(this); creo que le falta este codigo al checkbox del principio de la página .
Programar un CheckBox para que se comunicarse a una base de datos en android studio como lo podría hacer. Gracias.
Buen Dìa.
Muy excelente tutorial.
Tengo una duda respecto a la utilizaciòn del mètodo getCheckedRadioButtonId().
Al parecer, se declara en una variable tipo entera int.
Pero no tengo claro què mismo es lo que devuelve este mètodo, ya que lo he convertido en String para visualizar en un EditText y me decuelve un nùmero entero.
Favor explicarme bien este mètodo.
Hola, como hago para contabilizar y mostar las opciones seleccionadas de los checkboxes?
Es decir, si tengo 4 checkbox y selecciono 2, que me muestre la cantidad seleccionada y los mensajes de esa selección.
Muchas gracias!