Cómo crear aplicaciones accesibles con Flutter: Fuentes grandes, Lectores de pantalla y Suficiente contraste

La accesibilidad es la capacidad de hacer que una aplicación sea usable por la mayor cantidad de personas posible, incluyendo aquellas con discapacidades visuales, auditivas, motoras o cognitivas. Flutter se compromete a apoyar a los desarrolladores que quieren hacer sus aplicaciones más accesibles, ofreciendo tres componentes principales para el soporte de accesibilidad:

  • Fuentes grandes: Renderizar widgets de texto con tamaños de fuente especificados por el usuario.
  • Lectores de pantalla: Comunicar comentarios verbales sobre el contenido de la interfaz de usuario.
  • Suficiente contraste: Hacer widgets con colores que tengan suficiente contraste.

En este artículo, vamos a ver cómo usar estos componentes en Flutter y algunos consejos para mejorar la accesibilidad de nuestras aplicaciones.

Fuentes grandes

Tanto Android como iOS contienen configuraciones de sistema para configurar los tamaños de fuente deseados utilizados por las aplicaciones. Los widgets de texto de Flutter respetan esta configuración del sistema operativo cuando se determinan los tamaños de fuente. Esto significa que no tenemos que preocuparnos por definir tamaños de fuente fijos o absolutos en nuestros widgets, sino que podemos usar los valores relativos proporcionados por el tema de la aplicación.

Sin embargo, como desarrolladores, debemos asegurarnos de que nuestros layouts tengan espacio suficiente para mostrar todos sus contenidos cuando aumente el tamaño de las fuentes. Por ejemplo, podemos probar todas las partes de nuestra aplicación en un dispositivo de pantalla pequeña configurado para usar la configuración de fuente más grande. También podemos usar el widget Flexible para permitir que los widgets se adapten al espacio disponible, o el widget AutoSizedText del paquete auto_size_text para ajustar el tamaño del texto al tamaño del contenedor.

Lectores de pantalla

Los lectores de pantalla son herramientas que permiten a las personas con discapacidad visual acceder al contenido de las aplicaciones mediante comentarios verbales. Los lectores de pantalla más comunes son TalkBack en Android y VoiceOver en iOS. Estas herramientas pueden leer el texto, los botones, las imágenes y otros elementos de la interfaz de usuario, así como proporcionar gestos para navegar y realizar acciones.

Flutter utiliza un widget llamado Semantics para anotar el árbol de widgets con una descripción del significado de los widgets. Este widget es utilizado por las herramientas de accesibilidad para determinar el contenido y el comportamiento de la aplicación1. Por defecto, muchos widgets básicos como Text, Icon, Image o RaisedButton proporcionan información semántica adecuada para los lectores de pantalla. Sin embargo, podemos usar el widget Semantics para personalizar o añadir información semántica a nuestros widgets personalizados o compuestos.

Algunos ejemplos de propiedades que podemos definir en el widget Semantics son:

label: Un texto que describe el widget. Por ejemplo, podemos usar esta propiedad para dar un nombre a una imagen o un icono.

hint: Un texto que indica la acción que se puede realizar con el widget. Por ejemplo, podemos usar esta propiedad para indicar que un botón permite abrir otra pantalla o volver a la anterior.

value: Un texto que representa el valor actual del widget. Por ejemplo, podemos usar esta propiedad para indicar el valor de un slider o un switch.

enabled: Un valor booleano que indica si el widget está habilitado o no. Por ejemplo, podemos usar esta propiedad para deshabilitar un botón que no se puede pulsar.

onTap, onLongPress, onScrollLeft, etc.: Unas funciones que se ejecutan cuando el usuario realiza un gesto con el lector de pantalla activado. Por ejemplo, podemos usar estas propiedades para asignar acciones a los widgets que no son interactivos por defecto, como las imágenes o los iconos.

A continuación, se muestra un ejemplo de cómo usar el widget Semantics para añadir información semántica a un widget personalizado que muestra una imagen con un icono de favorito:

class FavoriteImage extends StatelessWidget {
  final String imageUrl;
  final bool isFavorite;

  const FavoriteImage({Key key, this.imageUrl, this.isFavorite}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.topRight,
      children: [
        Image.network(imageUrl),
        Semantics(
          label: 'Imagen de $imageUrl',
          child: Icon(
            isFavorite ? Icons.favorite : Icons.favorite_border,
            color: Colors.red,
            size: 48,
          ),
        ),
      ],
    );
  }
}

En este caso, hemos usado la propiedad label para dar un nombre a la imagen y al icono, y hemos omitido la propiedad hint porque el icono no es interactivo.

Si quisiéramos hacer que el icono fuera pulsable, podríamos añadir la propiedad onTap y un hint que describiera la acción.

Para probar cómo funciona el lector de pantalla con nuestra aplicación, podemos activar TalkBack o VoiceOver en nuestro dispositivo o emulador y navegar por los elementos de la interfaz usando los gestos disponibles.

También podemos usar el widget ExcludeSemantics para ocultar widgets que de otro modo serían leídos por los lectores pero que sólo serían confusos y no sería necesario leerlos. Por ejemplo, el widget Chip oculta el avatar ya que es redundante con la etiqueta del chip.

Suficiente contraste

El contraste es la diferencia de luminosidad entre el texto y el fondo. Un contraste suficiente es necesario para que el texto sea legible y no cause fatiga visual o dificultades a las personas con baja visión o daltonismo. Las pautas de accesibilidad web (WCAG) recomiendan una relación de contraste mínima de 4.5:1 para el texto normal y de 3:1 para el texto grande.

Flutter nos permite definir los colores de nuestros widgets usando el tema de la aplicación o directamente en los constructores de los widgets. Podemos usar herramientas online como WebAIM Color Contrast Checker o Material Design Color Tool para comprobar si los colores que elegimos cumplen con los criterios de contraste adecuados.

A continuación, se muestra un ejemplo de cómo definir los colores del tema de la aplicación usando el constructor ThemeData:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Accesibilidad en Flutter',
      theme: ThemeData(
        primaryColor: Colors.blue,
        accentColor: Colors.orange,
        textTheme: TextTheme(
          headline1: TextStyle(fontSize: 32.0, fontWeight: FontWeight.bold, color: Colors.white),
          bodyText1: TextStyle(fontSize: 16.0, color: Colors.black87),
        ),
      ),
      home: MyHomePage(),
    );
  }
}

En este caso, hemos usado los colores predefinidos de Flutter, que tienen un buen contraste entre ellos. Sin embargo, si quisiéramos usar otros colores personalizados, podríamos crearlos usando el constructor Color y pasando un valor hexadecimal como parámetro. Por ejemplo:

Color customColor = Color(0xFF00FF00); // Un verde brillante

Para usar los colores del tema en nuestros widgets, podemos acceder al contexto actual usando el método Theme.of y acceder a sus propiedades. Por ejemplo:

Text(
  'Hola, este es un texto con el color del tema',
  style: TextStyle(
    color: Theme.of(context).primaryColor,
  ),
);

Para cambiar los colores del tema de forma dinámica, podemos usar el widget Theme para envolver una parte de nuestra aplicación y pasarle un nuevo ThemeData con los colores que queramos. Por ejemplo:

Theme(
  data: ThemeData(
    primaryColor: Colors.red,
    accentColor: Colors.yellow,
  ),
  child: MyWidget(),
);

En este caso, el widget MyWidget y sus descendientes usarán los colores rojo y amarillo.

 

Conclusión

En este artículo hemos visto cómo usar los componentes de accesibilidad en Flutter para hacer nuestras aplicaciones más inclusivas y usables por la mayor cantidad de personas posible. Hemos aprendido cómo usar fuentes grandes, lectores de pantalla y suficiente contraste para mejorar la legibilidad, la comunicación y la interacción con nuestra interfaz de usuario. También hemos visto cómo usar el tema de la aplicación para definir y cambiar los colores y los estilos de fuente de forma consistente.

Espero que este artículo te haya sido útil y te anime a probar Flutter y a crear aplicaciones accesibles con este framework. Si quieres saber más sobre Flutter y sus posibilidades, puedes visitar su página web oficial.

Además, desde nuestra área de conocimiento EDEX (Emerging Devices Experience) hablaremos sobre la accesibilidad en Flutter en nuestro próximo evento el día 27 de abril. Regístrate en el evento y únete a nuestra charla sobre Flutter. Gracias por haberme leído y hasta la próxima.

Tags

He leído y acepto la política de privacidad
Acepto recibir emails sobre actividades de recruiting NTT DATA