El orden de recorrido es el orden en el que los servicios de accesibilidad navegan por los elementos de la IU. En una app de Compose, los elementos se organizan en el orden de lectura esperado, que suele ser de izquierda a derecha y, luego, de arriba abajo. Sin embargo, hay algunas situaciones en las que Compose podría necesitar sugerencias adicionales para determinar el orden de lectura correcto.
isTraversalGroup
y traversalIndex
son propiedades semánticas que te permiten influir en el orden de recorrido de los servicios de accesibilidad en situaciones en las que el algoritmo de ordenamiento predeterminado de Compose no es suficiente. isTraversalGroup
identifica los grupos semánticamente importantes que necesitan personalización, mientras que traversalIndex
ajusta el orden de los elementos individuales dentro de esos grupos.
Puedes usar isTraversalGroup
solo para indicar que todos los elementos de un grupo deben seleccionarse juntos, o con traversalIndex
para personalizarlos aún más.
Usa isTraversalGroup
y traversalIndex
en tu app para controlar el orden de recorrido del lector de pantalla.
Agrupa elementos para la navegación
isTraversalGroup
es una propiedad booleana que define si un nodo de semántica es un grupo de recorrido. Este tipo de nodo es aquel cuya función es servir como límite o borde para organizar los elementos secundarios del nodo.
Configurar isTraversalGroup = true
en un nodo significa que se visitan todos los elementos secundarios de ese nodo antes de pasar a otros elementos. Puedes establecer isTraversalGroup
en nodos que no sean enfocados por el lector de pantalla, como columnas, filas o cuadros.
En el siguiente ejemplo, se usa isTraversalGroup
. Emite cuatro elementos de texto. Los dos elementos de la izquierda pertenecen a un elemento CardBox
, mientras que los dos elementos de la derecha pertenecen a otro 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 ) } }
El código produce un resultado similar al siguiente:

Como no se estableció ninguna semántica, el comportamiento predeterminado del lector de pantalla es recorrer los elementos de izquierda a derecha y de arriba abajo. Debido a esta configuración predeterminada, TalkBack lee los fragmentos de oraciones en el orden incorrecto:
"Esta oración está en" → "Esta oración es" → "la columna izquierda". → "a la derecho".
Para ordenar los fragmentos correctamente, modifica el fragmento original para establecer isTraversalGroup
en 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 } ) } }
Debido a que isTraversalGroup
se establece específicamente en cada CardBox
, los límites de CardBox
se aplican cuando se ordenan sus elementos. En este caso, primero se lee el CardBox
izquierdo y, luego, el CardBox
derecho.
Ahora, TalkBack lee los fragmentos de la oración en el orden correcto:
"Esta oración está en" → "la columna izquierda". → “Esta oración está” → “a la derecha”.
Cómo personalizar el orden de recorrido
traversalIndex
es una propiedad de número de punto flotante que te permite personalizar el orden de recorrido de TalkBack. Si agrupar elementos no es suficiente para que TalkBack funcione correctamente, usa traversalIndex
junto con isTraversalGroup
para personalizar aún más el orden del lector de pantalla.
La propiedad traversalIndex
tiene las siguientes características:
- Los elementos con valores de
traversalIndex
más bajos tienen la prioridad. - Puede ser positivo o negativo.
- El valor predeterminado es
0f
. - Para que el índice de recorrido influya en el comportamiento de recorrido, se debe establecer en un componente que los servicios de accesibilidad puedan seleccionar y enfocar, como los elementos en pantalla, como el texto o los botones.
- Si solo configuras
traversalIndex
en, por ejemplo, unColumn
, no se producirá ningún efecto, a menos que la columna también tengaisTraversalGroup
configurado.
- Si solo configuras
En el siguiente ejemplo, se muestra cómo puedes usar traversalIndex
y isTraversalGroup
juntos.
Una cara de reloj es una situación común en la que no funciona el orden de recorrido estándar. El ejemplo de esta sección es un selector de hora, en el que un usuario puede recorrer los números de una cara de reloj y seleccionar dígitos para las ranuras de hora y minuto.

En el siguiente fragmento simplificado, hay un CircularLayout
en el que se dibujan 12
números, comenzando con 12 y moviéndose en el sentido de las manecillas del reloj alrededor del 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()) } }
Debido a que la cara de reloj no se lee de forma lógica con el orden predeterminado de izquierda a derecha y de arriba abajo, TalkBack lee los números desordenados. Para rectificar esto, usa el valor del contador incremental, como se muestra en el siguiente fragmento:
@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 configurar correctamente el orden de recorrido, primero haz que CircularLayout
sea un grupo de recorrido y establece isTraversalGroup = true
. Luego, a medida que cada texto del reloj se dibuja en el diseño, establece su traversalIndex
correspondiente en el valor del contador.
Debido a que el valor del contador aumenta de forma continua, el traversalIndex
de cada valor de reloj es mayor a medida que se agregan números a la pantalla. El valor de reloj 0 tiene un traversalIndex
de 0 y el valor de reloj 1 tiene un traversalIndex
de 1.
De esta manera, se establece el orden en que TalkBack los lee. Ahora, los números dentro de CircularLayout
se leen en el orden esperado.
Debido a que los traversalIndexes
que se establecieron solo son relativos a otros índices dentro de la misma agrupación, se conservó el resto del orden de la pantalla. En otras palabras, los cambios semánticos que se muestran en el fragmento de código anterior solo modifican el orden dentro de la cara de reloj que tiene configurado isTraversalGroup = true
.
Ten en cuenta que, sin configurar la semántica de CircularLayout's
en isTraversalGroup =
true
, los cambios de traversalIndex
aún se aplican. Sin embargo, sin el CircularLayout
para vincularlos, los doce dígitos de la cara de reloj se leen por último, después de que se visitaron todos los demás elementos de la pantalla. Esto ocurre porque todos los demás elementos tienen un traversalIndex
predeterminado de 0f
, y los elementos de texto del reloj se leen después de todos los demás elementos 0f
.
Consideraciones de la API
Ten en cuenta lo siguiente cuando uses las APIs de recorrido:
isTraversalGroup = true
se debe establecer en el elemento superior que contiene los elementos agrupados.traversalIndex
se debe establecer en un componente secundario que contenga semántica y que los servicios de accesibilidad seleccionarán.- Asegúrate de que todos los elementos que investigues estén en el mismo nivel de
zIndex
, ya que eso también afecta la semántica y el orden de recorrido. - Asegúrate de que no se combinen semánticas innecesariamente, ya que esto puede afectar a los índices de recorrido de componentes a los que se aplican.
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Accesibilidad en Compose
- [Material Design 2 en Compose][19]
- Cómo probar tu diseño de Compose