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 fontSize
s.
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.
- 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.
- 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.