Descripción general de la implementación (II): la aplicación no responde
Contenidos
Foto de Gabriella Clare Marino en Unsplash
introducción
En el artículo anterior, dimos una descripción general de los principios de accesibilidad y presentamos los principios correspondientes. API de aleteo. Hoy vamos a explorar diferentes formas en las que podemos agregar a11y (abreviatura de accesibilidad) a nuestras aplicaciones.
Lluvia de ideas sobre posibles implementaciones
Existen diferentes enfoques para abordar la accesibilidad, tales como:
- alguno ad hoc Solución agregando los widgets de semántica directamente en nuestro árbol de widgets
- crear personalizado widgets accesibles
- a través del uso extensiones
- cualquier mezcla los enfoques anteriores
En las siguientes secciones, entraremos en detalles sobre cada una de estas opciones.
1. Solución ad hoc
Esta primera implementación es bastante simple. Aprovechamos eso Widgets de accesibilidad y propiedades a11y en la API de Flutter y aplicarlo en todo el código de nuestra aplicación. Por ejemplo, digamos que queremos una imagen o Símbolo con una descripción alternativa. Simplemente usamos la propiedad semántica apropiada: const Icon( Icons.flutter_dash_rounded, size: 100,
etiqueta semántica: «¡Esta imagen muestra el logo de Flutter, Dash!», ) Al trabajar con widgets que no tienen semántica, podemos anidarlos en un componente de «semántica»: volver semántica(
Valor: «Bienvenido a la App Accesible», child: MaterialApp( …. ), ); Así que nada especial aquí, esta solución es obvia. En ambos casos, la siguiente tabla resume las ventajas y desventajas:
VENTAJAS | Desventajas |
Simplemente | Detallado |
¡Efectivo, hace el trabajo! | Código ad hoc repetitivo en toda la aplicación |
propenso a errores |
Implementación ad hoc ¿Podemos hacerlo aún mejor? Vamos a ver…
2. Widgets personalizados
El enfoque anterior nos obliga a escribir mucho código (repetitivo). Y en la mayoría de los casos, más código significa más errores. Podemos mejorarlo por Cree widgets personalizados reutilizables que encapsulen la semántica Es importante para nosotros evitar repeticiones de código. Por ejemplo, podemos tener nuestro propio “Custom”.Texto accesible” clase que agrega automáticamente algunas propiedades de accesibilidad a cualquier texto. Debajo de eso, esta clase usa la API Flutter nuevamente, pero ya no entraremos en ella directamente ya que la clase proporciona eso su propia API: Clase Texto accesible Extended StatelessWidget { texto de cadena final; última cuerda? altDescrip; constante Texto accesible({requerido this.text, this.altDescrip}}) : super(); @override Widget build(BuildContext context) { return Text(texto, …
etiqueta semántica: altDescripción ?? Texto, ); } } En esta solución obtenemos total Control sobre la implementación y la API También ofrecemos otras clases. Además, todos los detalles están encapsulados en nuestra clase personalizada. Digamos que queremos hacer ese enlace descripción alternativa Propiedad. Simplemente marcamos el parámetro apropiado como requerido: clase Texto accesible Extended StatelessWidget { texto de cadena final; Cadena final altDescrip; constante Texto accesible({requerido this.text, requerido this.altDescrip}): super(); @override Widget build(BuildContext context) { return Text(texto, …
etiqueta semántica: altDescrip, ); } } O tal vez queremos cambiar eso Apariencia y comportamiento del texto mostrado. Al aplicar un estilo predeterminado o usar el estilo que inyectamos a través del constructor, lo hacemos: Clase Texto accesible Extended StatelessWidget { texto de cadena final; Cadena final altDescrip; estilo de texto final? Estilo; constante Texto accesible({requerido este.texto, requerido este.altDescrip, este.estilo, super.clave}): super(); @override Widget build(BuildContext context) { return Text( texto,
estilo: estilo ?? Tema.de(contexto).textoTema.cuerpoMedio,
etiqueta semántica: altDescrip, ); } } Esta solución simplemente aplica algunos principios básicos de la programación orientada a objetos (POO), como la abstracción, la encapsulación o la herencia. De todos modos, la siguiente tabla resume este enfoque:
VENTAJAS | Desventajas |
Control sobre API e impl. | explosión de clase |
principios de programación orientada a objetos | Implementación «costosa» |
Haz el trabajo (¡otra vez!) | Mayor nivel de abstracción |
Implementación de widgets personalizados No está mal, pero ¿hay margen de mejora…?
3. Extensiones… al rescate
La implementación anterior requeriría un esfuerzo significativo ya que necesitamos crear un nuevo conjunto de widgets accesibles. En algunos escenarios, incluso podría ser imposible. Así que necesitamos algo «más ligero»… Como probablemente sepas, Flutter admite extensiones Por defecto. Con extensiones podemos Agregar comportamientos a las clases, incluso si no somos «dueños» de la clase para extender. Debajo del capó, las extensiones se implementan como métodos estáticos con parámetros sofisticados, pero el proceso es completamente transparente para nosotros. Por ejemplo, podemos usar extensiones para personalizar el comportamiento de la clase String predeterminada. Los pasos requeridos son: Expandir CustomString a String { String captialize(){ return substring(0,1).toUppercase(). subcadena(1).toLowercase(); } }
- Llame al método desde un objeto String en cualquier parte de nuestro código:
«accesibilidad».capitalizar() Se ve bien, ¿no? Aplicando la misma idea, podemos aprovechar el poder de las extensiones Envuelva automáticamente cada widget en un widget de «semántica»: extension SemanticsExtension on Widget { Semantics semantics({required String descrip}) => Semantics( value: descrip, child: this, ); } La principal ventaja de este enfoque es Conveniencia: Es muy fácil llamar a la extensión personalizada y aplicar accesibilidad a cualquier componente en nuestro árbol de widgets. const Text( ‘Aquí hay algo de texto…’, ).semantics( descrip: «Alguna descripción de accesibilidad…»), Como hicimos con los enfoques anteriores, analicemos también esta solución:
VENTAJAS | Desventajas |
Implementación «barata» | Resolución estática |
Cómodo | |
sintaxis concisa |
Implementación de extensiones
Apéndice I: Prueba de Accesibilidad
El Paquete de prueba de aleteo incluye funciones integradas para garantizar que nuestra aplicación satisfaga algunas de las necesidades más comunes Pautas comunes de accesibilidad. Básicamente, las pruebas de widgets para a11y parecen pruebas de interfaz de usuario normales, pero usan algunos nuevos comparadores para verificar si nuestros widgets cumplen con los principios POUR. Por cierto, ten esto en cuenta cualquier plataforma (Android, iOS) tiene su Directrices propias para contenidos accesibles., y estos pueden ser ligeramente diferentes: por ejemplo, una plataforma requiere un tamaño mínimo de 46 píxeles para las superficies que se pueden tocar, mientras que la otra requiere 48 píxeles, y así sucesivamente. Al probar la accesibilidad, usamos la clase SemanticsHandle para acceder a los datos almacenados en el árbol semántico. Podemos obtener una instancia de él a través del objeto probador de widgets y eliminarlo cuando ya no lo necesitemos: SemanticsHandle? manejar testWidgets(«Algunas pruebas de accesibilidad», (Tester) async { handle = tester.ensureSemantics(); … handle?.dipose(); } Dentro de todas las pruebas, algunas de las emparejadores comunes Son:
- tapTargetGuideline: asegúrese de que las áreas que se pueden tocar sean lo suficientemente grandes
- textContrastGuideline: asegúrese de que el texto de un tamaño y color específicos sea legible cuando se usa sobre un fondo específico
- etiquetadoTapTargetGuideline: asegúrese de que todas las acciones tengan sus etiquetas descriptivas apropiadas
Apéndice II: Semántica localizada
El paquete intl proporciona soporte de accesibilidad de forma predeterminada. Cada vez que agregamos una copia a la colección de cadenas de nuestra aplicación, también podemos agregar el texto de descripción alternativo correspondiente.
Código fuente
El código fuente completo se puede encontrar en el repositorio a continuación. Contiene varias ramas denominadas “característica/xxx_enfoque‘, que corresponden a las implementaciones discutidas en el artículo. https://github.com/begomez/Flutter-Accesibilidad
referencias
https://docs.flutter.dev/development/accessibility-and-localization/accessibility
Como esto:
Me gusta Cargando…