Focar no Compose

Quando um usuário interage com seu app, ele geralmente toca em elementos na tela. No entanto, essa não é a única forma de interação. Outras formas de interação podem incluir o seguinte:

  • Um usuário do ChromeOS pode usar as teclas de seta no teclado físico para navegar na tela.
  • Alguém pode usar o controle de jogo conectado para navegar pelo menu do jogo.
  • Um usuário de app para dispositivos móveis pode alternar entre elementos usando o teclado na tela.

Nesses casos, é importante acompanhar qual componente está ativo em um determinado momento, o que é o que chamamos de focus. Os elementos da tela precisam estar focados em uma ordem lógica. O Jetpack Compose tem uma maneira padrão de lidar com o foco que está correta na maioria dos casos. No entanto, em alguns casos, pode ser necessário modificar esse comportamento padrão.

As páginas a seguir descrevem como usar o foco no seu app:

  • Mudar a ordem de travessia de foco: explica como mudar a ordem de foco padrão, adicionar grupos de foco e desativar o foco de um elemento combinável.
  • Mudar o comportamento do foco: descreve como solicitar, capturar e liberar o foco, além de como redirecionar o foco ao entrar em uma tela.
  • Reagir ao foco: explica como reagir a mudanças de foco, adicionar indicações visuais aos elementos e entender o estado do foco de um elemento.

Ordem de travessia de foco padrão

Antes de analisar o comportamento padrão da pesquisa de foco, é importante entender o conceito de nível na hierarquia: de modo geral, podemos dizer que dois Composables estão no mesmo nível quando são irmãos, o que significa que eles têm os mesmos pais. Por exemplo, os elementos dentro de uma Column estão no mesmo nível. Subir um nível significa ir de um filho para o pai Composable ou, manter o mesmo exemplo, voltar de um item para uma Column que o contém. O processo de descer um nível é o contrário, do elemento pai Column para os itens contidos nele. Esse conceito pode ser aplicado a cada Composable que possa conter outro Composables.

A navegação pela IU pode acontecer de várias maneiras, das quais a maioria dos usuários já sabe:

  • GUIAS: navegação unidimensional, avançar ou retroceder. A navegação por TAB avança o foco para o elemento seguinte ou anterior na hierarquia. Por padrão, o Compose segue a declaração do Composables. A navegação unidirecional pode ser realizada usando a tecla tab no teclado ou a borda rotativa em um relógio, e esse tipo de pesquisa de foco acessa cada elemento na tela.
  • Teclas de seta: navegação bidimensional, para a esquerda, para a direita, para cima ou para baixo. A navegação bidimensional pode ser realizada com um D-pad em uma TV ou teclas de seta em um teclado, e a ordem de travessia só visita elementos em um determinado nível. Você pode usar o botão direcional central e o botão "Voltar" para descer e voltar para um nível diferente.

Veja como exemplo a captura de tela abaixo, na qual você tem quatro botões, um abaixo do outro, e quer alternar entre eles em ordem de aparência. O Jetpack Compose oferece esse comportamento pronto para uso: o kit de ferramentas permite percorrer cada elemento combinável em ordem vertical, de cima para baixo, usando a tecla tab, ou mover o foco, pressionando a seta para cima ou para baixo.

Captura de tela de uma lista de botões posicionados verticalmente um abaixo do outro em um formato pequeno.
Figura 1. Lista de botões exibidos em um formato pequeno.

Quando você muda para um tipo diferente de layout, as coisas mudam um pouco. Caso seu layout tenha mais de uma coluna, como o layout abaixo, o Jetpack Compose permite navegar por elas sem precisar adicionar código. Se você pressionar a tecla tab, o Jetpack Compose destacará automaticamente os itens na ordem de declaração, do primeiro ao quarto. Usar as teclas de seta no teclado faz com que a seleção siga a direção desejada no espaço 2D.

Column {
    Row {
        TextButton({ }) { Text("First field") }
        TextButton({ }) { Text("Second field") }
    }
    Row {
        TextButton({ }) { Text("Third field") }
        TextButton({ }) { Text("Fourth field") }
    }
}

As Composables são declaradas em dois Rows, e os elementos de foco são declarados em ordem, do primeiro ao quarto. Ao pressionar a tecla tab, a ordem de foco abaixo é produzida:

Captura de tela de uma lista de botões colocados em duas colunas lado a lado em um formato maior.
Figura 2. Lista de botões colocados em duas colunas lado a lado em um formato maior

No snippet abaixo, você declara os itens em Columns, e não em Rows:

Row {
    Column {
        TextButton({ }) { Text("First field") }
        TextButton({ }) { Text("Second field") }
    }
    Column {
        TextButton({ }) { Text("Third field") }
        TextButton({ }) { Text("Fourth field") }
    }
}

Esse layout atravessa os itens verticalmente, de cima para baixo, do início da tela ao fim:

Captura de tela de uma lista de botões colocados em duas colunas lado a lado em um formato maior.
Figura 3. Lista de botões colocados em duas colunas lado a lado em um formato maior

Os dois exemplos anteriores, embora diferem na navegação unidirecional, oferecem a mesma experiência quando se trata da navegação bidimensional. Isso geralmente ocorre porque os itens na tela têm a mesma localização geográfica nos dois exemplos. Navegar para a direita da primeira Column move o foco para o segundo, e navegar para baixo do primeiro Row move o foco para o abaixo.