CheckBox: Controles En Android

Si andas buscando permitir al usuario la selección de múltiples opciones con respecto al contenido de tu app Android, entonces este tutorial sobre el control CheckBox te será de gran ayuda en tus desarrollos.

En el aprenderás a:

  • Cómo usar checkboxes
  • Añadir un checkbox en Android Studio
  • Obtener su estado y modificarlo en tiempo de ejecución
  • Manejar eventos de chequeo
  • Personalizar estilo y colores

Descargar Proyecto En Android Studio

El siguiente video ilustra todos los conocimientos que obtendrás una vez termines este tutorial:

Si deseas desbloquear el enlace para descargar el código, sigue estas instrucciones:

Crear Proyecto En Android Studio

1. Para probar las prácticas que verás en este artículo primero debes crear un proyecto en Android Studio que se ajuste al que yo usaré.

La configuración del proyecto general es:

  • Application Name: “Checkboxes”
  • Company Domain: “herprogramacion.com”
  • Projection Location:”D:\Proyectos_Android\Checkboxes”

2. Usa la versión del SDK mínima recomendada y añade una actividad al proyecto del tipo Empty Activity.

Personaliza la actividad con las siguientes características:

  • Activity Name: ActividadPrincipal
  • Layout Name: actividad_principal

Usando Un CheckBox En Android

Un Checkbox es un botón de dos estados (marcado, no marcado) que actúa como control de selección (los radio buttons y switches también pertenecen a esta categoría) ante los usuarios. Lo que permite elegir una o varias opciones de un conjunto.

Checkbox en Android

Por defecto su color será el mismo de la propiedad android:colorAccent en el tema de la aplicación.

Las especificaciones del Material Design sobres controles de selección nos muestra que este view puede pasar por 5 estados, tanto si está marcado como si no:

  • hover: Estado cuando el Checkbox se encuentra inmóvil
  • focused: Cuando la navegación en la UI apunta al checkbox como control de entrada
  • pressed: El checkbox se encuentra bajo selección prolongada
  • disable: El checkbox pierde su capacidad de cambio entre estados
  • disable-focused: El checkbox está deshabilitado pero el sistema de navegación lo enfoca

Las siguientes ilustraciones muestran los estados descritos anteriormente en el tema Material Light y Dark:

Estados checkbox en Material Design Light

Estados checkbox en Material Design Dark

La Clase CheckBox

La representación en Java de este control es con la clase CheckBox.

Esto quiere decir que debes usar la etiqueta <CheckBox> en tus layouts para crearlos en la vista.

Por ejemplo…

Abre el layout actividad_principal.xml y agrega un nuevo checkbox como muestra el siguiente código:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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"
    tools:context="com.herprogramacion.checkboxes.ActividadPrincipal">

    <CheckBox
        android:id="@+id/checkBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Recordarme" />
</RelativeLayout>

En la preview verás:

CheckBox en la Preview de Android Studio

Obtener Valor Del CheckBox

Si quieres saber en qué estado se encuentra actualmente el CheckBox utiliza el método isChecked().

El retorno es de tipo boolean, donde true significa checked y false unchecked.

Ejemplo

Obtener el estado de un checkbox y mostrarlo en un Toast al pulsarse el botón de guardar.

Solución

1. Ubica en el centro del RelativeLayout un CheckBox. En la parte inferior debes poner un Button que se extienda completamente de forma horizontal. Su atributo text tendrá el valor de “Guardar“.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <CheckBox
        android:id="@+id/seleccion_direccion_envio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Usar la misma dirección de facturación" />

    <Button
        android:id="@+id/boton_guardar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:onClick="loguearCheckbox"
        android:text="Guardar" />
</RelativeLayout>

2. Abre ActividadPrincipal.java y declara el método loguearCheckbox(). En su interior llama el método estático Toast.makeText() y loguea el estado del check box.

Obviamente lo primero es obtener su instancia y luego llamar a isChecked(). Usa las palabras “Marcado” y “No Marcado” dependiendo del valor retornado.

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;

public class ActividadPrincipal extends AppCompatActivity {

    private CheckBox seleccionDireccion;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actividad_principal);

        seleccionDireccion = (CheckBox) findViewById(R.id.seleccion_direccion_envio);
    }

    public void loguearCheckbox(View v) {
        String s = "Estado: " + (seleccionDireccion.isChecked() ? "Marcado" : "No Marcado");
        Toast.makeText(this, s, Toast.LENGTH_LONG).show();
    }
}

3. Al correr la app se verá el mensaje con el estado. Prueba ambos casos.

isChecked() en CheckBox

Marcar CheckBox

Para cambiar el estado de un checkbox usa el atributo booleano android:checked. Donde false (valor por defecto) equivale a no marcado y true hace efectiva la verificación.

Por ejemplo. La siguiente caja de confirmación viene marcado de forma predeterminada para indicar que una pizza tendrá como ingrediente adherido champiñones:

<CheckBox
    android:id="@+id/opcion_champinones"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="true"
    android:text="Champiñones" />

Por otro lado, la forma programática de modificar el valor se da con el método setChecked(), que recibe el estado como parámetro.

Ejemplo:

Aplicar seguro automáticamente si el giro a reclamar sobrepasa los 2000 USD.

Solución

1. El  layout para dicha situación se basa en un EditText que recibe el monto del giro y un CheckBox en la parte inferior de este, que determina si se aplican costos para asegurar el giro en caso de robo.

Esto en definición XML podría traducirse en un LinearLayout de orientación vertical con ambos views.

actividad_principal.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <android.support.design.widget.TextInputLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/campo_monto"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="Monto del giro"
            android:inputType="numberDecimal"
            android:singleLine="true" />
    </android.support.design.widget.TextInputLayout>

    <CheckBox
        android:id="@+id/opcion_asegurar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Aplicar seguro" />

</LinearLayout>

Nota: Usé un TextInputLayout para proporcionar etiquetas flotantes. Aprende a usarlo en mi artículo TextInputLayout En Android: Material Design.

2. Usa la interfaz TextWatcher para verificar el cambio del monto en el campo de texto. La idea es comprobar que el valor sea mayor o igual a 2000 para marcar el checkbox automáticamente a través de setChecked().

ActividadPrincipal.java

public class ActividadPrincipal extends AppCompatActivity {

    private CheckBox opcionAsegurar;
    private EditText campoMontoGiro;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actividad_principal);

        opcionAsegurar = (CheckBox) findViewById(R.id.opcion_asegurar);

        campoMontoGiro = (EditText) findViewById(R.id.campo_monto);
        campoMontoGiro.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                String str = s.toString();

                // Precondición
                if (TextUtils.isEmpty(str)) {
                    str = "0";
                }

                float monto = Float.parseFloat(str);

                if (monto >= 2000) {
                    opcionAsegurar.setChecked(true);
                }
            }
        });
    }
}

3. Digita un número mayor a 2000 y prueba la marcación automática:

Marcar CheckBox con setChecked() debido a EditText

Deshabilitar CheckBox

Usa el atributo general android:enabled con el valor de false para deshabilitar ante el usuario un CheckBox.

Ejemplo:

Mostrar las características premium de un software deshabilitadas ante un usuario que no tiene licencia válida.

Solución

Modifica el layout para que haya un TextView con un texto informativo sobre la limitación de cuentas premium. Por debajo sitúa dos checkboxes deshabilitados con las opciones nombradas abajo.

actividad_principal.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">


    <TextView
        android:id="@+id/texto_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Solo cuentas premium"
        android:textAppearance="@style/TextAppearance.AppCompat.Body2" />

    <CheckBox
        android:id="@+id/opcion_reporte"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:enabled="false"
        android:focusable="true"
        android:text="Generar reporte mensual" />

    <CheckBox
        android:id="@+id/opcion_ajuste_local"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:enabled="false"
        android:focusable="true"
        android:text="Envío ajustado a zona de tiempo local" />
</LinearLayout>

Deshabilitar CheckBox

Análogamente llama al método setEnabled() con el valor de false en su parámetro para deshabilitar.

Ejemplo:

Simula que el usuario presiona un botón de la parte inferior e inmediatamente obtiene una cuenta premium. En consecuencia, habilita las opciones restringidas.

Solución

1. Añade al layout el botón en la parte inferior:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Actualizar Cuenta"
    android:id="@+id/boton_actualizar"
    android:onClick="actualizarCuenta"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="16dp" />

2. Ahora procesa los clicks sobre el botón con el método actualizarCuenta(). Usa setEnabled() con el valor de true para habilitar las cajas de confirmación.

public class ActividadPrincipal extends AppCompatActivity {

    private View opcionReporte, opcionZona;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actividad_principal);

        opcionReporte = findViewById(R.id.opcion_reporte);
        opcionZona = findViewById(R.id.opcion_ajuste_local);

    }

    public void actualizarCuenta(View view) {
        opcionReporte.setEnabled(true);
        opcionZona.setEnabled(true);
    }
}

Método setEnabled() en CheckBox

CheckBox En Android Studio

En esta sección crearás un layout para presentar al usuario un conjunto de gustos que puede seleccionar para recomendar información de acuerdo a sus preferencias.

Aunque ubicar un CheckBox en la pestaña Design de Android Studio es intuitivo, este ejemplo te servirá como práctica si aún desconoces este aspecto.

1. Abre actividad_principal.xml y cambia todo el contenido por un nodo principal del tipo GridLayout. Este contenedor permitirá dividir en columnas el conjunto de datos.

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

</GridLayout>

2. Selecciona la pestaña Design y ubícate en la ventana Palette. Luego selecciona el view Plain Text en el grupo Widgets.

Arrastra el TextView a la celda definida en (0,0):

TextView en GridLayout

El view anterior es el texto de información para guiar al usuario. Usa en su atributo android:text el valor “Elige tus intereses”.

3. Ahora pon dos espacios. Uno en la celda (0,1) y otro en (1,0). Este elemento se encuentra en el grupo Expert al final de la paleta como Space.

Añadir Space en GridLayout

4. Ahora busca CheckBox en Widgets y agrega 5 elementos desde (2,0) a (6,0). Luego agrega otros 5 desde (2,2) hasta (6,2).

Cuadrícula de checkboxes en GridLayout

5. Ahora modifica el texto e id de cada checkbox. Puedes hacerlo a través del panel Properties, pero es más fácil dar doble click en cada elemento para hacerlo a través de un diálogo emergente.

Cambiar texto de checkbox

Usa las siguientes categorías en los textos: Belleza, Libros y Literatura, Carreras, Educación, Eventos, Familia, Comidas y Bebidas, Videojuegos, Deportes, Arte.

Para los identificadores solo emplea el formato campo_<interes>.

6. Si todo salió bien, el código resultante es el siguiente:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="0"
        android:layout_row="0"
        android:text="Elige tus intereses"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

    <Space
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_column="1"
        android:layout_row="0" />

    <Space
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_column="0"
        android:layout_row="1" />

    <CheckBox
        android:id="@+id/opcion_belleza"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="0"
        android:layout_row="2"
        android:checked="false"
        android:text="Belleza" />

    <CheckBox
        android:id="@+id/campo_libros_literatura"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="0"
        android:layout_row="3"
        android:checked="false"
        android:text="Libros y Literatura" />

    <CheckBox
        android:id="@+id/campo_comida_bebidas"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="2"
        android:layout_row="3"
        android:checked="false"
        android:text="Comida y Bebidas" />

    <CheckBox
        android:id="@+id/campo_carreras"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="0"
        android:layout_row="4"
        android:checked="false"
        android:text="Carreras" />

    <CheckBox
        android:id="@+id/campo_videojuegos"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="2"
        android:layout_row="4"
        android:checked="false"
        android:text="Videojuegos" />

    <CheckBox
        android:id="@+id/campo_educacion"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="0"
        android:layout_row="5"
        android:checked="false"
        android:text="Educación" />

    <CheckBox
        android:id="@+id/campo_deportes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="2"
        android:layout_row="5"
        android:checked="false"
        android:text="Deportes" />

    <CheckBox
        android:id="@+id/campo_eventos"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="0"
        android:layout_row="6"
        android:checked="false"
        android:text="Eventos" />

    <CheckBox
        android:id="@+id/campo_familia"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="2"
        android:layout_row="2"
        android:checked="false"
        android:text="Familia" />

    <CheckBox
        android:id="@+id/campo_arte"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_column="2"
        android:layout_row="6"
        android:checked="false"
        android:text="Arte" />

</GridLayout>

Conjunto de checkboxes para intereses

Manejo De Eventos

Procesar Clicks con OnClickListener

Si deseas ejecutar acciones cuando el usuario selecciona un CheckBox usa la escucha View.OnClickListener.

Recuerda que esta posee al controlador onClick() para especificar las acciones a realizar en tiempo de ejecución.

Solo debes asignar una instancia con setOnClickListener() a la instancia de la caja de confirmación.

Por ejemplo:

findViewById(R.id.opcion_tv).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Ejecutar acciones
    }
});

Otra forma es asignar un controlador genérico en el atributo android:onClick del checkbox como vimos en la sección de botones.

Ejemplo:

Revelar el password que el usuario escriba en el campo de texto si marca un CheckBox 

Solución

1. Añade un EditText centrado en un RelativeLayout con inputType tipo textPassword. Por debajo añade un CheckBox.

actividad_principal.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <CheckBox
        android:id="@+id/opcion_mostrar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/campo_contrasena"
        android:layout_alignStart="@+id/campo_contrasena"
        android:layout_below="@+id/campo_contrasena"
        android:onClick="mostrarContraseña"
        android:text="¿Mostrar contraseña?" />

    <EditText
        android:id="@+id/campo_contrasena"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:ems="10"
        android:hint="Contraseña"
        android:inputType="textPassword" />
</RelativeLayout>

2. Abre ActividadPrincipa.java y obtén las instancias de los views en onCreate(). Luego definir el controlador mostrarContrasena().

En su interior tendremos que comprobar con isChecked() si el checkbox está marcado. Si es así entonces cambia su tipo de entrada con setInputType() para tener el password visible.

De lo contrario asigna el tipo que tiene por defecto para enmascarar la contraseña.

Adicionalmente es necesario guardar la posición del cursor antes de aplicar el cambio de entrada, ya que setInputType() restaura el cursor a la posición 0.

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.InputType;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;

public class ActividadPrincipal extends AppCompatActivity {

    private CheckBox opcionMostrar;
    private EditText campoContrasena;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actividad_principal);

        opcionMostrar = (CheckBox)findViewById(R.id.opcion_mostrar);
        campoContrasena = (EditText)findViewById(R.id.campo_contrasena);
    }

    public void mostrarContraseña(View v){
        // Salvar cursor
        int cursor = campoContrasena.getSelectionEnd();

        if(opcionMostrar.isChecked()){
            campoContrasena.setInputType(InputType.TYPE_CLASS_TEXT
                    | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
        }else{
            campoContrasena.setInputType(InputType.TYPE_CLASS_TEXT
                    | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        }

        // Restaurar cursor
        campoContrasena.setSelection(cursor);
    }

}

Password visible en EditText con CheckBox

Cambios de Estado con OnCheckedChangeListener

La escucha CompoundButton.OnCheckedChangeListener permite realizar operaciones cuando el estado del botón cambia.

Para asignar una nueva instancia usa el método setOnCheckedChangeListener() en la instancia del CheckBox.

Luego sobrescribe el controlador onCheckedChanged() con las acciones que deseas ejecutar. Este método recibe dos parámetros.

  • buttonView: Hace referencia  al checkbox que cambió su estado.
  • isChecked: El estado al que cambió el checkbox.

Ejemplo:

Crear una pregunta para el usuario que identifique desde que canal supo sobre la compañía.

Las opciones son: Televisión, Radio, Periódico, Email, Amigos y Otros. 

Al seleccionar “Otros” debe mostrarse un campo para que escriba dichas fuentes.

Solución:

1. Modifica actividad_principal.xml donde exista:

  • Un TextView en la parte superior con el texto “¿Dónde oíste de nosotros?”
  • 5 elementos CheckBox en forma vertical con las opciones mencionadas.
  • Un EditText sin presencia (visibility en gone) por debajo de las opciones.

¿El resultado?

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/texto_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:text="¿Dónde oíste de nosotros?"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

    <CheckBox
        android:id="@+id/opcion_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="false"
        android:text="Tv" />

    <CheckBox
        android:id="@+id/opcion_radio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="false"
        android:text="Radio" />

    <CheckBox
        android:id="@+id/opcion_periodico"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="false"
        android:text="Periódico" />

    <CheckBox
        android:id="@+id/opcion_amigo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="false"
        android:text="Un amigo" />

    <CheckBox
        android:id="@+id/opcion_otros"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="false"
        android:text="Otros" />

    <EditText
        android:id="@+id/campo_otros"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:layout_marginTop="16dp"
        android:hint="¿Cuáles otros?"
        android:inputType="textMultiLine"
        android:lines="3"
        android:maxLines="3"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
</LinearLayout>

2. En el código Java obtén las instancias de la opción y el campo para “Otros”. Luego asigna la escucha OnCheckedChangeListener de forma anónima a opcion_campo.

En su controlador onCheckedChanged() cambia la visibilidad del campo de texto dependiendo del segundo parámetro. Para true usará la bandera VISIBLE y para false GONE.

public class ActividadPrincipal extends AppCompatActivity {

    private CheckBox opcionOtros;
    private View campoOtros;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actividad_principal);

        opcionOtros = (CheckBox) findViewById(R.id.opcion_otros);
        campoOtros = findViewById(R.id.campo_otros);

        opcionOtros.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                campoOtros.setVisibility(isChecked ? View.VISIBLE : View.GONE);
            }
        });
    }

}

Uso de OnCheckedChangeListener en CheckBox con EditText

Personalizar Estilo De CheckBox

Veamos algunos de los casos más frecuentes a la hora de cambiar el aspecto de un checkbox:

Cambiar Color en Estado Activo

Esto se puede hacer de dos formas:

1. Usar el atributo app:buttonTint para cambiar el tinte de la caja. Sin embargo en su estado OFF el borde será de ese mismo color.

<CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Personalizar"
    app:buttonTint="@color/colorPrimary"
    android:id="@+id/checkbox" />

 

2. Usar un tema propio personalizando el atributo colorAccent. Simplemente aplícalo al view con el atributo android:theme.

styles.xml

<style name="CheckBoxIndigo">
    <item name="colorAccent">@color/colorPrimary</item>
</style>

layout

<CheckBox
    android:id="@+id/checkbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Personalizar"
    android:theme="@style/CheckBoxIndigo" />

Cambiar color de CheckBox

Background Personalizado del Botón

Si deseas cambiar el background de la caja de confirmación usa el atributo android:button para signar un drawable de tipo lista, donde se especifiquen los estados marcado (state_checked) y no marcado.

Ejemplo:

Crear un background para un checkbox que sea circular y tenga color aguamarina.

Solución:

1. Crea un nuevo Drawable resource file para usar una definición XML con un nodo <selector>. En este deben existir dos ítems. El estado chequeado y el estado normal:

boton_checkbox.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/background_checkbox_on" android:state_checked="true" />
    <item android:drawable="@drawable/background_checkbox_off" />

</selector>

2. Crea dos drawables más para materializar la definición del background en cada estado. En este caso usaremos el nodo <vector> para construir un drawable de vector que simplifique la definición del icono.

background_checkbox_on.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="32dp"
    android:height="32dp"
    android:viewportHeight="48"
    android:viewportWidth="48">

    <group
        android:scaleX=".2"
        android:scaleY=".2"
        android:translateX="6"
        android:translateY="6">
        <group
            android:scaleX="7.5"
            android:scaleY="7.5">
            <path
                android:fillColor="#45D0BB"
                android:pathData="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z" />
        </group>
    </group>

</vector>

Background personalizado para CheckBox

background_checkbox_off.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="32dp"
    android:height="32dp"
    android:viewportHeight="48"
    android:viewportWidth="48">

    <group
        android:scaleX=".2"
        android:scaleY=".2"
        android:translateX="6"
        android:translateY="6">
        <group
            android:scaleX="7.5"
            android:scaleY="7.5">
            <path
                android:fillColor="#6E6E6E"
                android:pathData="M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" />
        </group>
    </group>
</vector>

Background personalizado para CheckBox en estado OFF

3. A continuación asigna el drawable de lista en el atributo android:button de un checkbox de ejemplo en actividad_principal.xml.

<CheckBox
    android:id="@+id/checkbox2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="48dp"
    android:button="@drawable/boton_checkbox"
    android:text="Personalizar" />

4. Ejecuta la app y observa el cambio de estados:

Ejemplo de cambios de estados en CheckBox

Añadir Un CheckBox Dinámicamente

En ocasiones tendrás una fuente de datos de la cual dependen tus Checkboxes.

Puede que la lista de nombres se encuentre en una arreglo de recursos, en una base de datos SQLite, que se provean desde un servicio web, desde un archivo xml, etc.

Así no es posible definir en el layout con anterioridad la cantidad exacta de checkboxes y su contenido explícitamente.

Lo que debes hacer es crearlos en tiempo de ejecución o dinámicamente a través del constructor de la clase CheckBox() y luego añadirlo con addView() en el contenedor padre.

Ejemplo:

Añadir un CheckBox por cada industria disponible para selección del usuario. La lista de datos se encuentra en un array

Solución

1. Primero cambia el contenido de actividad_principal.xml por un nodo LinearLayout que contenga una sección para las opciones. Dicha sección debe llevar un TextView con el mensaje “Selecciona tu industria:”.

Debido a que necesitas los checkboxes alineados verticalmente usa el atributo android:orientation con el valor vertical en la sección.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <LinearLayout
        android:id="@+id/seccion_industria"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/texto_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Selecciona tu industria:"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    </LinearLayout>
</LinearLayout>

2. Añade en la actividad principal un arreglo estático de strings con las siguientes industrias:

public static String[] INDUSTRIAS ={
        "Arte",
        "Computación",
        "Ingeniería civil",
        "Bioquímica",
        "Música",
        "Astronomía",
        "Zoología"
};

3. Para añadir en tiempo real cada checkbox primero obtén el contenedor seccion_industria con el método findViewById().

Luego emplea una estructura for que recorra todos los elementos de INDUSTRIAS. En cada iteración crea una instancia de CheckBox y añádela al contenedor con addView().

Súper importante que añadas al checkbox el texto con setText() antes de ser añadido. Además añade los parámetros de ancho y alto en formato “wrap content” a través de setLayoutParams().

ActividadPrincipal.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.ViewGroup.LayoutParams;
import android.widget.CheckBox;
import android.widget.LinearLayout;

public class ActividadPrincipal extends AppCompatActivity {

    public static String[] INDUSTRIAS = {
            "Arte",
            "Computación",
            "Ingeniería civil",
            "Bioquímica",
            "Música",
            "Astronomía",
            "Zoología"
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actividad_principal);

        LinearLayout seccionIndustria = (LinearLayout) findViewById(R.id.seccion_industria);

        for (String industria : INDUSTRIAS) {
            CheckBox opcion = new CheckBox(this);
            opcion.setText(industria);
            opcion.setLayoutParams(
                    new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            seccionIndustria.addView(opcion);
        }

    }

}

El constructor de la clase CheckBox() recibe como parámetro el contexto de referencia. Debido a que será la actividad principal es posible usar el operador this.

Agregar dinámicamente un checkbox en Android

checkbox-android

Conclusión

Ahora es tu turno de poner en práctica el uso del control CheckBox.

Puedes combinarlo en formularios con botones, campos de texto y otros controles de selección.

Incluso incluirlos en listas de datos para promover acciones grupales. O en diálogos y preferencias de usuario.

Todo depende del diseño de UI que hayas formulado para mejorar la experiencia de usuario.

  • Gabriel B.

    Hola James, primero que todo felicidades por el tutorial. Tengo una pequenna consulta que me tiene mi trabajo trabado. Como pudiera disparar el evento de varios fragments en una activity desde una opcion del menu????
    Agradeceria cualquier recomendacion. Saludos

    • Hola Gabriel, mmm tienes alguna imagen de lo que quieres hacer. Me cuesta imaginar que deseas realizar.

      • Gabriel B.

        Hola James, gracias por responder, ya resolví el problema, lastimosamente tuve que hacerlo con activities ya que por cuestión de tiempo de entrega no me era posible mucha investigación.
        un saludo desde Cuba

  • Luis David Guzman

    Fantastico, excelente tutorial, aprendi muchas cosas que no sabia acerca de los checkbox, :) Gracias !!!

  • Gon Her

    Muy buen tutorial. Hace unos dias tuve la necesidad de agregar unos CheckBox en mi proyecto, al final no los pude usar porque cada vez que se lanza la app, estos vuelven a su estado por defecto. Es decir que: quiero poner un texto con un CheckBox. si el usuario marca el CheckBox es que no quiere volver a ver ese texto. marca el CheckBox pero al iniciar la app siempre está desmarcado el CheckBox, utilicé todos los metodos arriba mensionados. Un saludos grande!

    • Prueba en guardar el estado en SharedPreferences cuando se clickea y cuando se abre la app consultas su estado, para así activarlo o desactivarlo antes de mostrase.