33

I needed to make my entire app independed from device's font size settings. I found that I could set textScaleFactor: 1.0 for every text view manualy. It's a good solution for a few Text widgets, but not good for a big app with dozens of Text widgets.

Oleksandr
  • 1,396
  • 1
  • 8
  • 14
  • The ```MaterialApp``` has a ```theme``` attribute, you can customise it and it will be applied to all widgets enclosed in your material app. It will be a bit tricky to find out which attribute is used for every widget but it's doable :). – danypata Dec 02 '19 at 16:59

6 Answers6

75

First things first I have to say that it's a bad idea to make your text irrelevant to phone settings. It makes your app less friendly for users with disabilities such as blindness or motor impairment. As a developer you should make sure your layout has enough room to render all it's contents when the font sizes are increased. But sometimes we actualy need font size to be fixed.

All you have to do is create Material App Builder to set Media Query property "textScaleFactor: 1.0" for the entire app.

MaterialApp(
  builder: (context, child) {
    return MediaQuery(
      child: child,
      data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
    );
   },
)

Solution was found here.

Ichigo Kurosaki
  • 3,765
  • 8
  • 41
  • 56
Oleksandr
  • 1,396
  • 1
  • 8
  • 14
  • 2
    this does not work on assesibility settings – user1034912 Apr 24 '21 at 07:41
  • 5
    How does this work if you don't supply a builder and instead use the 'home' parameter for my MaterialApp? – Scorb Dec 20 '21 at 19:19
  • Problem with this approach is you are losing user experience, user might need to change font size for his/her vision problem but you are limiting him to use the same font size you gave. You can follow @Pratik Butani answers for this situation. – Md omer arafat Oct 06 '22 at 05:54
  • For Null Safety use [this](https://stackoverflow.com/a/73937338/13601462) – Denver Shenal Oct 21 '22 at 01:02
44

You are right Oleksandr, Setting the textScaleFactor to 1.0 and calling it a day means ignoring your user's needs. They’re asking for a bigger text size and you are not delivering it.

Let's make it more adaptive

You can choose minimum factor and maximum factor and that you can give comparatively.

return MaterialApp(
        builder: (context, child) {
          final mediaQueryData = MediaQuery.of(context);
          final scale = mediaQueryData.textScaleFactor.clamp(1.0, 1.3);
          return MediaQuery(
            child: child,
            data: MediaQuery.of(context).copyWith(textScaleFactor: scale),
          );
        },
);

Instead of a hardcoded textScaleFactor, we can give a constrained system value.

By using clamp(), we're giving the system textScaleFactor a lower and upper bound.

Source : Restricting system textScaleFactor, when you have to

Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
  • 2
    Wait where does this go? what is `child` – Petro Jan 18 '22 at 21:40
  • 1
    ```child``` is the widget here. – Arijeet Jul 20 '22 at 12:36
  • This is the perfect way to manage this Font size adaptive issue without losing user experience. – Md omer arafat Oct 06 '22 at 05:52
  • 1
    @Mdomerarafat Only partially. You'd clamp the value in a way that still is adequate to your boundaries, but if the client is almost blind and uses massive font sizes, text will still be too small. But agreed, this is better than forcing `1.0` scale factor. – Martin Braun Oct 16 '22 at 02:38
2

This Is working in my Project

return MaterialApp(
      home:Container(),
      builder: (context, child) {
        return MediaQuery(
          child: child!,
          data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
        );
      },
    );

With Getx

GetMaterialApp(
              debugShowCheckedModeBanner: false,
              theme: ThemeData(primaryColor: AppColor().colorPrimary),
              translations: LocaleString(),
              navigatorKey:navigatorKey,
              locale:
                  Locale(Utils.language.value, Utils.language_country.value),
              routes: Routes.getRoutes(),
                builder:(context,child){
                  return MediaQuery(data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), child: child);
                }
            );
General Grievance
  • 4,555
  • 31
  • 31
  • 45
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 12 '23 at 00:21
1

Use like this:

MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Container(child: SplashScreen()),
          builder: (context, child) {
            return MediaQuery(
              child: child!,
              data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
            );
          },
        ),
Nisha Jain
  • 637
  • 6
  • 14
1

The @Pratik Butani Answer is absolutely right. But If you are returning GetMaterialApp or any other widget. Remember the builder must be in bottom.

 return GetMaterialApp(

      theme: ThemeData(
        textTheme: GoogleFonts.aBeeZeeTextTheme(
          Theme.of(context).textTheme
        )
      ),

      initialBinding: MainBinding(),
      debugShowCheckedModeBanner: false,
      initialRoute: Routes.splashRoute,
      getPages: Routes.routes,

        builder:(context,child){
        final mediaQueryData = MediaQuery.of(context);
        final scale = mediaQueryData.textScaleFactor.clamp(0.8, 0.9);
          return MediaQuery(data: MediaQuery.of(context).copyWith(textScaleFactor: scale), child: child!);
        }
    );
mufazmi
  • 1,103
  • 4
  • 18
  • 37
1

Here the simple solution to prevent breaking UI when change device font settings

Use this code for solution inside the main.dart under Material app

 builder: (context, child) {
              return MediaQuery(
                data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
                child: child,
              );
            },

Here the sample code

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'App Title',
        theme: theme(),
        initialRoute: SplashScreen.routeName,
        routes: routes,
        ///Here the code for prevent font size when change mobile
        builder: (context, child) {
          return MediaQuery(
            data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
            child: child,
          );
        },
    );
  }
Rahul Raj
  • 1,010
  • 9
  • 10