How to manage global textScaleFactor in Flutter app properly?

This solution was presented during Google I/O'19 (around the 20-minute mark):

MaterialApp(
  builder: (BuildContext context, Widget child){
    final MediaQueryData data = MediaQuery.of(context);
    return MediaQuery(
      data: data.copyWith(
        textScaleFactor: data.textScaleFactor * (_isPassive ? 2 : 1)
      ),
      child: child,
    );
  },

If you wish that everything had a fixed textScaleFactor, you could replace data.textScaleFactor * (_isPassive ? 2 : 1) for a single number. 1.0 would make your design to always follow your fontSizes.


You can set a limit after which you don't need to scale, as some apple apps do.

MaterialApp(
  builder: (BuildContext context, Widget child) {
    final MediaQueryData data = MediaQuery.of(context);
    return MediaQuery(
      data: data.copyWith(
        textScaleFactor: data.textScaleFactor > 2.0 ? 2.0 : data.textScaleFactor),
        child: child,
       );
    },
  debugShowCheckedModeBanner: false,
  title: 'Flutter app',
)

In addition, I added 2 functions that calculate the size for different cases.

  1. Always returns a fixed text size, for any textScaleFactor:
double getFixedSize(double textSize) {
  return textScaleFactor != 1.0 ? textSize / textScaleFactor : textSize;
}

For example, you can use it for app title text.

  1. Returns scaled textSize until specific scale is not reached, which is set by the second maxScaleFactor parameter:
double getScaledOrMaxSize(double textSize, double maxScaleFactor) {
 return textScaleFactor > maxScaleFactor
   ? textSize * maxScaleFactor / textScaleFactor
   : textSize;
}

This can be used for example for headers that are already large and you don't need to increase them even more.

I hope this helps you make good apps for visually impaired people while still leaving them beautiful.