Cómo reaccionar al enfoque

Cada vez que cambia el enfoque en el árbol de composición, Compose activa un evento de enfoque que pueden observar los modificadores principales y secundarios. Puedes usar el modificador onFocusChanged para detectar transiciones de estado de enfoque, consultar las propiedades de enfoque actuales y activar actualizaciones de la IU basadas en el estado.

Cómo observar el estado de enfoque con onFocusChanged

El modificador onFocusChanged proporciona un objeto FocusState cada vez que un elemento gana o pierde el enfoque.

Por ejemplo, puedes observar los cambios de enfoque para actualizar el estado del componente personalizado (como cambiar el color del borde de un elemento o activar una animación):

var color by remember { mutableStateOf(Color.White) }
Card(
    modifier = Modifier
        .onFocusChanged {
            color = if (it.isFocused) Red else White
        }
        .border(5.dp, color)
) {}

En este ejemplo, remember almacena el color del borde en todas las recomposiciones, y el color del borde se actualiza cada vez que el estado de enfoque del elemento realiza una transición.

Propiedades de FocusState

El objeto FocusState que se pasa a onFocusChanged proporciona tres propiedades clave:

  • isFocused: Devuelve true si el elemento componible específico al que se adjunta este modificador actualmente tiene el enfoque de entrada activo.
  • hasFocus: Devuelve true si este elemento componible o cualquiera de sus elementos componibles secundarios tienen el enfoque actualmente. Esto es útil para los contenedores principales (como tarjetas o barras de herramientas) que necesitan saber cuándo está activo alguno de sus elementos secundarios.
  • isCaptured: Devuelve true si el enfoque está bloqueado actualmente en el elemento (por ejemplo, durante las interacciones secundarias modales con captureFocus()). Mientras se captura, intentar mover el enfoque a otros elementos no borra el enfoque.
Modifier.onFocusChanged { focusState ->
    val isFocused = focusState.isFocused
    val hasFocus = focusState.hasFocus
    val isCaptured = focusState.isCaptured
}