Cómo reaccionar al enfoque

Proporciona indicaciones visuales para facilitar la visualización del enfoque

Si bien todos los elementos enfocables del tema de Material ya tienen un estilo de enfoque que coincide con el tema, es posible que debas agregar algunos elementos visuales para que el elemento enfocado sea más fácil de detectar. Una buena solución sería cambiar el borde de tu elemento con un color que tenga un buen contraste con el fondo:

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 se usa para almacenar el color del borde entre recomposiciones, y el contorno del elemento se actualiza cada vez que el elemento gana o pierde enfoque.

Implementa indicadores visuales avanzados

Con Jetpack Compose, también puedes crear elementos visuales más sofisticados y avanzados que se adapten mejor a tu IU.

  1. Primero, crea un IndicationInstance que dibuje visualmente la indicación que deseas en tu IU:
    private class MyHighlightIndicationInstance(isEnabledState: State<Boolean>) :
        IndicationInstance {
        private val isEnabled by isEnabledState
        override fun ContentDrawScope.drawIndication() {
            drawContent()
            if (isEnabled) {
                drawRect(size = size, color = Color.White, alpha = 0.2f)
            }
        }
    }
  2. A continuación, crea un objeto Indication y recuerda el estado enfocado:
    class MyHighlightIndication : Indication {
        @Composable
        override fun rememberUpdatedInstance(interactionSource: InteractionSource):
            IndicationInstance {
            val isFocusedState = interactionSource.collectIsFocusedAsState()
            return remember(interactionSource) {
                MyHighlightIndicationInstance(isEnabledState = isFocusedState)
            }
        }
    }
  3. Agrega Indication y InteractionSource a la IU mediante el modificador indication():
    val highlightIndication = remember { MyHighlightIndication() }
    var interactionSource = remember { MutableInteractionSource() }
    
    Card(
        modifier = Modifier
            .clickable(
                interactionSource = interactionSource,
                indication = highlightIndication,
                enabled = true,
                onClick = { }
            )
    ) {}

Comprende el estado del enfoque

Por lo general, cada vez que cambia un estado del enfoque, se activa un FocusEvent en el árbol, y los elementos superiores de un modificador focusable() pueden escucharlo con el modificador onFocusChanged().

Si necesitas conocer el estado del enfoque,puedes usar estas APIs junto con el modificador onFocusChanged:

  • isFocused muestra true si el elemento componible al que se adjunta el modificador está enfocado
  • hasFocus funciona de manera similar a isFocused, pero con una diferencia importante: en lugar de verificar solo el elemento actual, comprueba si el elemento o uno de sus elementos secundarios está enfocado
  • isCaptured muestra true cuando se mantiene el enfoque. Esto sucede, por ejemplo, cuando un TextField contiene datos incorrectos, de modo que intentar enfocar otros elementos no borrará el enfoque.

Estos campos se muestran a continuación:

Modifier.onFocusChanged {
    val isFocused = it.isFocused
    val hasFocus = it.hasFocus
    val isCaptured= it.isCaptured
}