Flutter Accessibility: Getting Started

Learn how to improve the accessibility of your Flutter app by providing more semantic details for screen readers and following other items from Flutter’s accessibility checklist. By Alejandro Ulate Fallas.

Leave a rating/review
Download materials
Save for later

Building a high-quality app is not only about its features and looks but also about how accessible it is to users, including people with disability.

In this tutorial, you’ll add accessibility features to a Flutter food recipe app. In the process, you’ll:

  • Learn about accessibility and its importance in mobile apps.
  • Differentiate between various accessibility needs.
  • Understand the built-in Flutter accessibility features.
  • Run through an accessibility checklist suggested by Flutter’s documentation.
  • Add accessibility support to a production-ready app called Mealize.

Are you ready to dive in?

Note: This tutorial assumes you have intermediate knowledge of Flutter and state management with the Bloc library. To learn more about those topics, check out Bloc 8.0 Tutorial for Flutter: Getting Started or Bloc’s documentation and tutorials.

Getting Started

Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.

Then, open the starter project in VS Code 1.70 or later. You can also use Android Studio, but you’ll have to adapt the instructions below.

Use Flutter version 3 or above. VS Code will prompt you to get dependencies. Click to do so.

If VS Code doesn’t get the dependencies automatically, open pubspec.yaml and click Get Packages in the top right corner or run flutter pub get from the integrated terminal.

In this article, you’ll add accessibility features to Mealize, a Flutter app that allows you to get a random recipe for cooking. You can also save recipes for later.

Exploring the Starter Project

Here’s a quick rundown of the project setup:

  • main.dart: Standard main file required for Flutter projects.
  • domain.dart: Contains the business logic and corresponding class definitions.
  • data.dart: Contains the classes that interact with storage and allows for better data handling.
  • app: A folder with the app widget and also a helper file with colors defined by the brand guidelines.
  • presentation: Contains different folders that build the app’s UI:
    • cubit defines a cubit that handles saved meals.
    • pages contains the two pages — meal_detail_page.dart and saved_meals_page.dart.
    • widgets contains custom widgets.
  • cubit defines a cubit that handles saved meals.
  • pages contains the two pages — meal_detail_page.dart and saved_meals_page.dart.
  • widgets contains custom widgets.

Build and run the project.

Here’s what you’ll see:

Screenshot of Mealize first run without Flutter accessibility

Note: Because accessibility features are only available on physical devices, you’ll need to use a physical Android or iOS device. The tutorial mostly showcases a Pixel 4 Android phone.

Because Flutter has accessibility built in, the app has some accessibility support. But, there’s room for improvement — and that’s what you’ll do in this tutorial.

But before you start your modifications, it’s important to understand why your Flutter app should be accessibile.

Why Accessibility is Important

Sometimes, it might seem inconvenient to add accessibility to your app. For example, if your app is already published, or if you want to get it to market as soon as possible, accessibility might not be at the top of your list.

But, there are several convincing reasons for making your app accessible. Here’s a short list you can refer to the next time you have to make a decision:

  1. Moral reasons: Developing apps without accessibility limits your app to only people without any form of disability. That means you’re excluding certain people from your product even though your intentions might not be malevolent. So, you must design and develop your apps so that anyone can use them, regardless of physical or cognitive abilities.
  2. Legal reasons: Since the United Nations established the Convention on the Rights of Persons with Disabilities in 2007, a few countries have put regulations in place to ensure that individuals with disabilities have equal access to infrastructure, jobs, education and digital services. In Norway, for instance, commercial websites cannot deny those with impairments equal access. Customer protection laws requiring most public websites to meet accessibility standards were put into effect in Austria in 2006. 10,982 ADA Title III lawsuits were filed in the US in 2020 alone. So, it’s probably best to ensure your mobile app is accessible to avoid the risk of legal action.
  3. Business reasons: More than 1 billion people live with some form of disability. Adding accessibility support to your app will increase your reach and improve your brand’s reputation. Also, there are about $6.9 trillion reasons from a business sense.
  4. Quality reasons: Since general usability relates to accessibility, you get more human-centered, natural and contextual interactions with your app. That results in higher product quality and a greater, much richer user experience.

The Built-in Flutter Accessibility

Flutter has great built-in accessibility support. By making an app with Flutter, you get:

  • Compatibility with large fonts.
  • Response to scale factor changes.
  • Support for screen readers.
  • Great color contrast defaults: Both material and cupertino have widgets with colors that have enough contrast when rendered.

In addition, the Flutter Team compiled an accessibility release checklist for you to consider as you prepare your release. In the next sections, you’ll review this checklist for Mealize.

Making Interactions Visible

It’s time to start adding accessibility to Mealize.

Build and run. Tap Random Meal to open a meal. Then, tap the Bookmark+ icon button to save it for later. Next, tap the Bookmark icon:

Animated GIF showing there are missing active interactions in Mealize

Did the actions complete? If so, when did each one finish? Could you tell if an action ended even if you could not see the screen?

See the problem yet?

These types of interactions can be invisible to people with visual problems. In fact, the only way to notice that you saved a meal for later is to pay close attention to the bookmark icons.

The app should tell the user what happened when they tapped the button. You’ll work on this first.

Open lib/presentation/widgets/meal_appbar.dart and replace the code in _onSaveMealForLater with the following:

final messenger = ScaffoldMessenger.maybeOf(context);
// TODO add directionality and semanticsLabel fields
await context.read<DetailCubit>().bookmarkMeal();

  behavior: SnackBarBehavior.floating,
  content: Text('Saved $mealName for later.'),
// TODO: Add Semantics for iOS.

With the code above, you display a floating Snackbar when saving a meal for later. This improves the interaction for impaired users and the user experience.

You also added two TODO remarks you’ll address later in the tutorial. For now, ignore them.

Now do the same for _onRemoveMeal — replace the code inside it with the following lines:

final messenger = ScaffoldMessenger.maybeOf(context);
// TODO add directionality and semanticsLabel fields
await context.read<DetailCubit>().removeBookmark();

  behavior: SnackBarBehavior.floating,
  content: Text('Removed $mealName from Saved Meals list.'),
// TODO: Add undo dangerous actions.

// TODO: Add Semantics for iOS.

Like the previous code, the code shows a snackbar when you remove a meal from the saved meals list.

Restart the app. Notice both snackbars when you save a meal for later or remove it from the saved list:

Animated GIF showing active interactions via SnackBars, improving the Flutter app's accessibility

Great job! You added your first bit of accessibility features to your Flutter app.