Flutter apps react on system large text making all Text widgets really large. I want to limit textScaleFactor for Text widgets but I want to do it globally not in each Text widget that I'am using.
Now after enabling large text I got exceptions like
flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ flutter: The following message was thrown during layout: flutter: A RenderFlex overflowed by 14 pixels on the bottom.
What is proper way to do it? One way is to create some wrapper widget instead of using Text, but maybe it can be solved other way?
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.
To limit the textScaleFactor for ALL PAGES in your app, you can do this.
Wrap your MaterialApp
with a MediaQuery
widget with the desired MediaQueryData
data which is created from the window
.
And set useInheritedMediaQuery
to true
.
@override
Widget build(BuildContext context) {
MediaQueryData windowData =
MediaQueryData.fromWindow(WidgetsBinding.instance!.window);
windowData = windowData.copyWith(
textScaleFactor:
windowData.textScaleFactor > 1.4 ? 1.4 : windowData.textScaleFactor,
);
return MediaQuery(
data: windowData,
child: MaterialApp(
useInheritedMediaQuery: true,
//...
),
);
}
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.
double getFixedSize(double textSize) {
return textScaleFactor != 1.0 ? textSize / textScaleFactor : textSize;
}
For example, you can use it for app title text.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With