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
se deben seleccionar juntos, o con traversalIndex para una mayor personalización.
Usa isTraversalGroup y traversalIndex en tu app para controlar el orden de recorrido del lector de pantalla.
Agrupa elementos para el recorrido
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 nodos secundarios.
Establecer 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 se pueden enfocar con 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 este comportamiento predeterminado, TalkBack lee los fragmentos de la oración en el orden incorrecto:
"This sentence is in" → "This sentence is" → "the left column." → "on the right."
Para ordenar los fragmentos de forma correcta, 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 de la izquierda y, luego, el CardBox de la derecha.
Ahora, TalkBack lee los fragmentos de la oración en el orden correcto:
"Esta oración está en" → "la columna izquierda". → "This sentence is" → "on the right."
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
traversalIndexmás bajos se priorizan primero. - 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 texto o botones.
- Establecer solo
traversalIndexen, por ejemplo, unColumnno tendría ningún efecto, a menos que la columna también tenga establecidoisTraversalGroup.
- Establecer solo
En el siguiente ejemplo, se muestra cómo puedes usar traversalIndex y
isTraversalGroup juntos.
Una cara de reloj es un caso común en el que el orden de recorrido estándar no funciona. 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 los espacios de hora y minuto.
En el siguiente fragmento simplificado, hay un CircularLayout en el que se dibujan 12 números, comenzando con el 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 a abajo, TalkBack lee los números en desorden. Para corregir esto, usa el valor del contador de incremento, 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 establecer correctamente el orden de recorrido, primero convierte el CircularLayout en un grupo de recorrido y establece isTraversalGroup = true. Luego, a medida que se dibuja cada texto del reloj 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 el 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 establecer la semántica de CircularLayout's en isTraversalGroup =
true, se siguen aplicando los cambios de traversalIndex. Sin embargo, sin el CircularLayout para vincularlos, los doce dígitos de la cara de reloj se leen al final, 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 API
Ten en cuenta lo siguiente cuando uses las APIs de recorrido:
isTraversalGroup = truese debe establecer en el elemento superior que contiene los elementos agrupados.traversalIndexse 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 investigas 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 de forma innecesaria, ya que esto puede afectar los componentes a los que se aplican los índices de recorrido.
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