Reagir ao foco

Fornecer indicações visuais para facilitar a visualização de foco

Embora todos os elementos focalizáveis do Material Theme já tenham um estilo de foco que corresponda ao tema, talvez seja necessário adicionar alguns elementos visuais para tornar elemento em foco mais fácil de encontrar. Uma boa solução seria mudar a borda seu elemento com uma cor que tenha um bom contraste com o plano de fundo:

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

Neste exemplo, remember é usado para armazenar a cor da borda recomposições, e o contorno do elemento é atualizado sempre que ele ganha ou perde o foco.

Implementar indicações visuais avançadas

Com o Jetpack Compose, você também pode criar recursos visuais mais sofisticados e avançados que combinem melhor com sua interface.

  1. Primeiro, crie um IndicationInstance que desenhe visualmente o estímulo que você quer na interface:
    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. Em seguida, crie uma Indication e lembre-se do estado em foco:
    class MyHighlightIndication : Indication {
        @Composable
        override fun rememberUpdatedInstance(interactionSource: InteractionSource):
            IndicationInstance {
            val isFocusedState = interactionSource.collectIsFocusedAsState()
            return remember(interactionSource) {
                MyHighlightIndicationInstance(isEnabledState = isFocusedState)
            }
        }
    }
  3. Adicione o Indication e um InteractionSource à interface usando o modificador indication():
    val highlightIndication = remember { MyHighlightIndication() }
    var interactionSource = remember { MutableInteractionSource() }
    
    Card(
        modifier = Modifier
            .clickable(
                interactionSource = interactionSource,
                indication = highlightIndication,
                enabled = true,
                onClick = { }
            )
    ) {}

Entender o estado do foco

Geralmente, toda vez que um estado do foco muda, um FocusEvent é acionado. a árvore, e os pais de um modificador focusable() podem ouvi-la usando o Modificador onFocusChanged().

Se você precisar saber o estado do foco,use essas APIs em conjunto com o modificador onFocusChanged:

  • isFocused vai retornar true se o elemento combinável ao qual o modificador estiver anexado está em foco
  • hasFocus funciona de maneira semelhante a isFocused, mas com uma diferença substancial: em vez de verificar apenas o atual, ele verifica se o elemento ou um de seus as crianças são focadas
  • isCaptured retorna true sempre que o foco é mantido. Isso acontece, quando uma TextField contém dados incorretos, de modo que tentar se concentrar outros elementos não limparão o foco.

Esses campos são mostrados abaixo:

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