☑️ CheckBox en Jetpack Compose

Aprende a crear opciones de selección múltiple

🎥 Video Tutorial

Mira este video completo para aprender a implementar CheckBox:

¿Qué es un CheckBox?

El componente CheckBox permite al usuario seleccionar MÚLTIPLES opciones simultáneamente. A diferencia del RadioButton (solo una opción), aquí puedes elegir todas las que necesites.

Ejemplo Visual:

Sumar
Restar
Multiplicar

✓ Puedes seleccionar una, varias o todas las opciones

🔘 RadioButton

  • Solo UNA opción
  • Selección excluyente
  • Círculo seleccionado

☑️ CheckBox

  • MÚLTIPLES opciones
  • Selección independiente
  • Cuadro con check

📐 Layout Row

Usaremos Row para organizar el CheckBox y el Text horizontalmente:

🎯 Row + verticalAlignment:
  • Row: Ubica elementos uno al lado del otro (horizontal)
  • verticalAlignment: Alinea los elementos en el eje vertical
  • CenterVertically: Centra verticalmente dentro del Row
Row(verticalAlignment = Alignment.CenterVertically) {
    // CheckBox y Text alineados verticalmente
}

💾 Variables Observables

Necesitamos crear una variable observable por cada CheckBox. Si tienes 5 CheckBox, creas 5 variables.

🔑 Conceptos Clave:
  • mutableStateOf(false) → Crea un estado mutable observable con valor inicial false (no seleccionado)
  • rememberSaveable → Recuerda el estado incluso cuando el usuario gira la pantalla
  • by → Delegado que permite acceder al valor sin usar .value
var suma by rememberSaveable { mutableStateOf(false) }
var resta by rememberSaveable { mutableStateOf(false) }
var multiplicar by rememberSaveable { mutableStateOf(false) }
⚠️ Importante:

Cada CheckBox necesita su propia variable porque pueden estar seleccionados independientemente. No puedes usar una sola variable para múltiples CheckBox.

🔨 Cómo Crear un CheckBox

El CheckBox tiene dos parámetros obligatorios:

📋 Parámetros obligatorios:
  • checked: Boolean que indica si está seleccionado
  • onCheckedChange: Lambda que se ejecuta al cambiar el estado
Row(verticalAlignment = Alignment.CenterVertically) {
    Checkbox(
        checked = suma,
        onCheckedChange = {
            suma = it
        }
    )
    Text(text = "Sumar")
}

¿Cómo funciona onCheckedChange?

Usuario hace clic
Se invoca onCheckedChange
Ejecuta lambda
Actualiza estado
✅ Flujo detallado:
  1. Usuario selecciona/deselecciona el CheckBox
  2. Se invoca onCheckedChange(Boolean)
  3. Se ejecuta la lambda { suma = it }
  4. it contiene el nuevo estado (true si seleccionado, false si no)
  5. Se actualiza la variable observable suma
  6. La UI se recompone mostrando el nuevo estado
🔍 ¿Qué es "it"?

it es el parámetro implícito de la lambda que contiene el nuevo estado del CheckBox:

  • it = true → CheckBox seleccionado ✓
  • it = false → CheckBox no seleccionado ☐

🔢 Múltiples CheckBoxes

Para crear varios CheckBoxes, simplemente repetimos el patrón con diferentes variables:

var suma by rememberSaveable { mutableStateOf(false) }
var resta by rememberSaveable { mutableStateOf(false) }
var multiplicar by rememberSaveable { mutableStateOf(false) }

// CheckBox Sumar
Row(verticalAlignment = Alignment.CenterVertically) {
    Checkbox(
        checked = suma,
        onCheckedChange = { suma = it }
    )
    Text("Sumar")
}

// CheckBox Restar
Row(verticalAlignment = Alignment.CenterVertically) {
    Checkbox(
        checked = resta,
        onCheckedChange = { resta = it }
    )
    Text("Restar")
}

// CheckBox Multiplicar
Row(verticalAlignment = Alignment.CenterVertically) {
    Checkbox(
        checked = multiplicar,
        onCheckedChange = { multiplicar = it }
    )
    Text("Multiplicar")
}

🔧 Función Composable Reutilizable

Para evitar repetir código, creamos una función reutilizable:

Crear la función Check

@Composable
fun Check(
    text: String,
    isSelected: Boolean,
    actualizarEstado: (Boolean) -> Unit
) {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 8.dp)
    ) {
        Checkbox(
            checked = isSelected,
            onCheckedChange = {
                actualizarEstado(it)
            }
        )
        Text(
            text = text,
            modifier = Modifier.padding(start = 8.dp)
        )
    }
}
📚 Parámetros explicados:
1 text: String

Texto personalizado para cada CheckBox ("Sumar", "Restar", etc.)

2 isSelected: Boolean

Estado actual del CheckBox (true = seleccionado, false = no seleccionado)

3 actualizarEstado: (Boolean) → Unit

Callback que se invoca cuando el usuario cambia el estado. Recibe el nuevo valor y no devuelve nada.

Cómo usar la función

var suma by rememberSaveable { mutableStateOf(false) }
var resta by rememberSaveable { mutableStateOf(false) }
var multiplicar by rememberSaveable { mutableStateOf(false) }

// Uso simple y limpio
Check("Sumar", suma) { suma = it }
Check("Restar", resta) { resta = it }
Check("Multiplicar", multiplicar) { multiplicar = it }
✅ Flujo de actualización:
  1. Usuario hace clic en el CheckBox "Restar"
  2. Dentro de la función Check, se invoca actualizarEstado(it)
  3. Esto ejecuta la lambda { resta = it } que pasamos al llamar la función
  4. it contiene el nuevo estado (true o false)
  5. Se actualiza la variable resta
  6. La UI se recompone automáticamente
💡 Concepto Callback:

Un callback es una función que se pasa como parámetro y se invoca en un momento específico. En este caso, actualizarEstado es un callback que se invoca cuando el usuario cambia el CheckBox, y nos permite actualizar la variable observable desde donde llamamos la función.

📊 Código Manual vs Reutilizable

❌ Sin función reutilizable

Row(...) {
  Checkbox(...)
  Text(...)
}
Row(...) {
  Checkbox(...)
  Text(...)
}
Row(...) {
  Checkbox(...)
  Text(...)
}

30+ líneas repetitivas

✅ Con función reutilizable

Check("Sumar", suma) {
  suma = it
}
Check("Restar", resta) {
  resta = it
}
Check("Multiplicar", m) {
  multiplicar = it
}

9 líneas limpias