De forma predeterminada, se implementa el comportamiento del lector de pantalla de accesibilidad en una app de Compose.
en el orden de lectura esperado, que suele ser de izquierda a derecha y, luego, de arriba a abajo.
Sin embargo, hay algunos tipos de diseños de apps en los que el algoritmo no puede determinar
el orden de lectura real sin sugerencias adicionales. En las aplicaciones basadas en vistas, puedes hacer lo siguiente:
corrige estos problemas con las propiedades traversalBefore
y traversalAfter
.
A partir de Compose 1.5, Compose proporciona una API igual de flexible, pero con
un nuevo modelo conceptual.
isTraversalGroup
y traversalIndex
son propiedades semánticas que
te permiten controlar la accesibilidad y el orden de enfoque de TalkBack en situaciones en las que la
el algoritmo de ordenamiento predeterminado no es apropiado. isTraversalGroup
identifica
grupos semánticamente importantes, mientras que traversalIndex
ajusta el orden de
elementos individuales dentro de esos grupos. Puedes usar solo isTraversalGroup
,
o con traversalIndex
para una mayor personalización.
Usa isTraversalGroup
y traversalIndex
en tu
para controlar el orden de recorrido del lector de pantalla.
Agrupa elementos con isTraversalGroup
isTraversalGroup
es una propiedad booleana que define si una semántica
es un grupo de recorrido. Este tipo de nodo es aquel cuya función es entregar
como límite o borde en la organización de los elementos secundarios del nodo.
Configurar isTraversalGroup = true
en un nodo significa que todos los elementos secundarios de ese nodo
antes de pasar a otros elementos. Puedes configurar isTraversalGroup
en
nodos enfocables de lectores que no son de pantalla, como Columnas, Filas o Cuadros.
En el siguiente ejemplo, se usa isTraversalGroup
. Emite cuatro elementos de texto. El
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ó una semántica, el comportamiento predeterminado del lector de pantalla es para recorrer los elementos de izquierda a derecha y de arriba abajo. Por este motivo De forma predeterminada, TalkBack lee los fragmentos de las oraciones en el orden incorrecto:
"Esta oración está en" → "Esta oración es" → "la columna de la izquierda". → "en la bien".
Para ordenar los fragmentos correctamente, modifica el fragmento original para establecer
De isTraversalGroup
a 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
se establece específicamente en cada CardBox
, la CardBox
se aplican límites al ordenar sus elementos. En este caso, el lado izquierdo
CardBox
se lee primero y, luego, la CardBox
derecha.
Ahora, TalkBack lee los fragmentos de oraciones en el orden correcto:
"Esta oración está en" → "la columna de la izquierda". → "Esta oración es" → "en la bien".
Cómo personalizar aún más el orden de recorrido
traversalIndex
es una propiedad de número de punto flotante que te permite personalizar TalkBack
orden transversal. Si agrupar elementos no es suficiente para que TalkBack
funcionan 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 se priorizan primero. - Pueden ser positivas o negativas.
- El valor predeterminado es
0f
. - Solo afecta a los nodos que se pueden enfocar en el lector de pantalla, como elementos en pantalla, como
el texto o los botones. Por ejemplo, configurar solo
traversalIndex
en una columna no tienen efecto, a menos que la columna también tenga configuradoisTraversalGroup
.
En el siguiente ejemplo, se muestra cómo puedes usar traversalIndex
y
isTraversalGroup
juntos.
Ejemplo: Desviar la cara de reloj
Una carátula es un escenario común donde el orden de recorrido estándar no el trabajo. El ejemplo de esta sección es un selector de hora, en el que un usuario puede por los números de una cara de reloj y seleccionar dígitos para la hora y los minutos las ranuras restantes.
En el siguiente fragmento simplificado, hay un CircularLayout
en el que 12
se dibujan números que comienzan con 12 y se mueven 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()) } }
Como la cara de reloj no se lee lógicamente con la opción predeterminada de izquierda a derecha y en orden descendente, TalkBack lee los números de forma desordenada. Para rectificar Para esto, utiliza el valor del contador creciente, 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 debes hacer que CircularLayout
sea un elemento
grupo de recorrido y configura isTraversalGroup = true
. Luego, como cada texto de reloj se
dibujado en el diseño, establece su traversalIndex
correspondiente en el contador
valor.
Debido a que el valor del contador aumenta continuamente, el valor de
traversalIndex
es más grande a medida que se agregan números a la pantalla (el valor de reloj es 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 lee las lecturas. Ahora bien, los números
dentro de CircularLayout
se leen en el orden esperado.
Como los traversalIndexes
que se configuraron solo son relativos a otros
dentro de la misma agrupación, el resto del orden de la pantalla se
y cómo se preservan. En otras palabras, los cambios semánticos que se muestran en el código anterior
solo modifican el orden dentro de la cara de reloj que tiene
Se estableció isTraversalGroup = true
.
Ten en cuenta que, si no se establece la semántica de CircularLayout's
en isTraversalGroup =
true
, se seguirán aplicando los cambios de traversalIndex
. Sin embargo, sin las
CircularLayout
para vincularlos, se leen los doce dígitos de la cara de reloj.
por último, después de haber visitado todos los demás elementos de la pantalla. Esto ocurre
porque todos los demás elementos tienen un traversalIndex
predeterminado de 0f
, y el
los elementos de texto del reloj se leen después de todos los demás elementos 0f
.
Ejemplo: Personaliza el orden de recorrido para el botón de acción flotante
En este ejemplo, traversalIndex
y isTraversalGroup
controlan la
Orden de recorrido de un botón de acción flotante (BAF) de Material Design. La base
de este ejemplo es el siguiente diseño:
De forma predeterminada, el diseño de este ejemplo tiene el siguiente orden de TalkBack:
Barra superior de la app → Textos de ejemplo 0 a 6 → botón de acción flotante (BAF) → Parte inferior Barra de la app
Es posible que quieras que el lector de pantalla se enfoque primero en el BAF. Para establecer un
traversalIndex
en un elemento de Material, como un BAF, haz lo siguiente:
@Composable fun FloatingBox() { Box(modifier = Modifier.semantics { isTraversalGroup = true; traversalIndex = -1f }) { FloatingActionButton(onClick = {}) { Icon(imageVector = Icons.Default.Add, contentDescription = "fab icon") } } }
En este fragmento, la creación de un cuadro con
Se estableció isTraversalGroup
en true
y se estableció traversalIndex
en el mismo cuadro
(-1f
es menor que el valor predeterminado de 0f
) significa que el cuadro flotante
aparece antes que los demás elementos en pantalla.
Luego, puedes colocar la caja flotante y otros elementos en un andamiaje, implementa un diseño de Material Design:
@OptIn(ExperimentalMaterial3Api::class) @Composable fun ColumnWithFABFirstDemo() { Scaffold( topBar = { TopAppBar(title = { Text("Top App Bar") }) }, floatingActionButtonPosition = FabPosition.End, floatingActionButton = { FloatingBox() }, content = { padding -> ContentColumn(padding = padding) }, bottomBar = { BottomAppBar { Text("Bottom App Bar") } } ) }
TalkBack interactúa con los elementos en el siguiente orden:
BAF → Barra superior de la app → Textos de ejemplo 0 a 6 → Barra inferior de la app
Recursos adicionales
- Accesibilidad: conceptos esenciales y técnicas comunes a todo el desarrollo de apps para Android
- Compila apps accesibles: Pasos clave que puedes realizar para que tu app sea más accesible
- Principios para mejorar la aplicación accesibilidad: Los principios clave para tener en cuenta cuando trabajes para hacer que tu aplicación sea más accesible
- Prueba de accesibilidad: Principios y herramientas de prueba para la accesibilidad de Android