A ordem de apresentação é a ordem em que os serviços de acessibilidade navegam pelos elementos da interface. Em um app Compose, os elementos são organizados na ordem de leitura esperada, que geralmente é da esquerda para a direita e de cima para baixo. No entanto, há alguns casos em que o Compose pode precisar de dicas adicionais para determinar a ordem correta de leitura.
isTraversalGroup
e traversalIndex
são propriedades semânticas que
permitem influenciar a ordem de travessia para serviços de acessibilidade em cenários
em que o algoritmo de classificação padrão do Compose não é suficiente. isTraversalGroup
identifica grupos semanticamente importantes que precisam de personalização, enquanto
traversalIndex
ajusta a ordem de elementos individuais nesses grupos.
É possível usar isTraversalGroup
sozinho para indicar que todos os elementos de um grupo
precisam ser selecionados juntos ou com traversalIndex
para mais personalização.
Use isTraversalGroup
e traversalIndex
no
app para controlar a ordem de passagem do leitor de tela.
Agrupar elementos para a travessia
isTraversalGroup
é uma propriedade booleana que define se um nó de semântica
é um grupo de travessia. Esse tipo de nó tem a função de servir
como limite ou borda na organização dos filhos do nó.
Definir isTraversalGroup = true
em um nó significa que todos os filhos desse nó
são visitados antes de passar para outros elementos. É possível definir isTraversalGroup
em
nós com foco que não são leitores de tela, como colunas, linhas ou caixas.
O exemplo a seguir usa isTraversalGroup
. Ele emite quatro elementos de texto. Os
dois elementos à esquerda pertencem a um elemento CardBox
, enquanto os dois elementos
à direita pertencem a outro elemento CardBox
:
// CardBox() function takes in top and bottom sample text. @Composable fun CardBox( topSampleText: String, bottomSampleText: String, modifier: Modifier = Modifier ) { Box(modifier) { Column { Text(topSampleText) Text(bottomSampleText) } } } @Composable fun TraversalGroupDemo() { val topSampleText1 = "This sentence is in " val bottomSampleText1 = "the left column." val topSampleText2 = "This sentence is " val bottomSampleText2 = "on the right." Row { CardBox( topSampleText1, bottomSampleText1 ) CardBox( topSampleText2, bottomSampleText2 ) } }
O código produz uma saída semelhante a esta:

Como nenhuma semântica foi definida, o comportamento padrão do leitor de tela é percorrer os elementos da esquerda para a direita e de cima para baixo. Por causa desse padrão, o TalkBack lê os fragmentos da frase na ordem errada:
"Esta frase está em" → "Esta frase está" → "na coluna esquerda." → "à direita".
Para ordenar os fragmentos corretamente, modifique o snippet original para definir
isTraversalGroup
como true
:
@Composable fun TraversalGroupDemo2() { val topSampleText1 = "This sentence is in " val bottomSampleText1 = "the left column." val topSampleText2 = "This sentence is" val bottomSampleText2 = "on the right." Row { CardBox( // 1, topSampleText1, bottomSampleText1, Modifier.semantics { isTraversalGroup = true } ) CardBox( // 2, topSampleText2, bottomSampleText2, Modifier.semantics { isTraversalGroup = true } ) } }
Como isTraversalGroup
é definido especificamente em cada CardBox
, os limites de CardBox
são aplicados ao classificar os elementos. Nesse caso, o CardBox
esquerdo é lido primeiro, seguido pelo CardBox
direito.
Agora, o TalkBack lê os fragmentos da frase na ordem correta:
"Esta frase está na" → "coluna esquerda." → "Esta frase está" → "na direita."
Personalizar a ordem de apresentação
traversalIndex
é uma propriedade float que permite personalizar a ordem de
navegação do TalkBack. Se agrupar elementos não for suficiente para que o TalkBack
funcione corretamente, use traversalIndex
em conjunto com
isTraversalGroup
para personalizar ainda mais a ordem do leitor de tela.
A propriedade traversalIndex
tem as seguintes características:
- Os elementos com valores de
traversalIndex
mais baixos são priorizados primeiro. - Pode ser positivo ou negativo.
- O valor padrão é
0f
. - Para que o índice de translação influencie o comportamento de translação, ele precisa ser
definido em um componente que será selecionável e focalizável por serviços de
acessibilidade, como elementos na tela, como texto ou botões.
- Definir apenas
traversalIndex
em, por exemplo, umColumn
não teria nenhum efeito, a menos que a coluna também tenhaisTraversalGroup
definido.
- Definir apenas
O exemplo a seguir mostra como usar traversalIndex
e
isTraversalGroup
juntos.
Um mostrador de relógio é um cenário comum em que a ordenação de travessia padrão não funciona. O exemplo desta seção é um seletor de horário, em que o usuário pode percorrer os números em um mostrador do relógio e selecionar dígitos para os intervalos de hora e minuto.

No snippet simplificado a seguir, há uma CircularLayout
em que 12
números são desenhados, começando com 12 e se movendo no sentido horário ao redor do círculo:
@Composable fun ClockFaceDemo() { CircularLayout { repeat(12) { hour -> ClockText(hour) } } } @Composable private fun ClockText(value: Int) { Box(modifier = Modifier) { Text((if (value == 0) 12 else value).toString()) } }
Como o mostrador de relógio não é lido de forma lógica com a ordem padrão da esquerda para a direita e de cima para baixo, o TalkBack lê os números fora de ordem. Para corrigir isso, use o valor de incremento do contador, conforme mostrado no snippet a seguir:
@Composable fun ClockFaceDemo() { CircularLayout(Modifier.semantics { isTraversalGroup = true }) { repeat(12) { hour -> ClockText(hour) } } } @Composable private fun ClockText(value: Int) { Box(modifier = Modifier.semantics { this.traversalIndex = value.toFloat() }) { Text((if (value == 0) 12 else value).toString()) } }
Para definir corretamente a ordem de travessia, primeiro torne o CircularLayout
um
grupo de travessia e defina isTraversalGroup = true
. Em seguida, conforme cada texto do relógio é
desenhado no layout, defina o traversalIndex
correspondente como o valor
do contador.
Como o valor do contador aumenta continuamente, o traversalIndex
de cada valor do relógio
é maior à medida que os números são adicionados à tela. O valor do relógio 0
tem um traversalIndex
de 0, e o valor do relógio 1 tem um traversalIndex
de 1.
Dessa forma, a ordem em que o TalkBack os lê é definida. Agora, os números
dentro do CircularLayout
são lidos na ordem esperada.
Como os traversalIndexes
definidos são relativos a outros
índices no mesmo grupo, o restante da ordem da tela foi
preservado. Em outras palavras, as mudanças semânticas mostradas no snippet de código
anterior modificam apenas a ordem dentro do mostrador do relógio que tem
isTraversalGroup = true
definido.
Sem a definição da semântica CircularLayout's
como isTraversalGroup =
true
, as mudanças traversalIndex
ainda se aplicam. No entanto, sem o
CircularLayout
para vinculá-los, os doze dígitos do mostrador do relógio são lidos
por último, depois que todos os outros elementos na tela são visitados. Isso ocorre
porque todos os outros elementos têm um traversalIndex
padrão de 0f
, e os
elementos de texto do relógio são lidos depois de todos os outros elementos 0f
.
Considerações sobre APIs
Considere o seguinte ao usar as APIs de travessia:
isTraversalGroup = true
precisa ser definido no pai que contém os elementos agrupados.traversalIndex
precisa ser definido em um componente filho que contém semântica e será selecionado pelos serviços de acessibilidade.- Verifique se todos os elementos que você está investigando estão no mesmo
nível de
zIndex
, porque isso também afeta a semântica e a ordem de travessia. - Verifique se nenhuma semântica é mesclada desnecessariamente, já que isso pode afetar os componentes em que os índices de travessia são aplicados.
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Acessibilidade no Compose
- [Material Design 2 no Compose][19]
- Como testar o layout do Compose