How to set MediaQuery textScaleFactor throughout the application and not for each page

Viewed 385

Main

final query = MediaQuery.of(context);

return MediaQuery(
  data: query.copyWith(textScaleFactor: 1.4),
  child: MaterialApp(
     title: "Flutter Demo",
     initialRoute: '/loginPage',
  )
);
 ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (13775): The following assertion was thrown building MyApp(dirty, state: _MyAppState#38690):
I/flutter (13775): MediaQuery.of() called with a context that does not contain a MediaQuery.
I/flutter (13775): No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery.of().
I/flutter (13775): This can happen because you do not have a WidgetsApp or MaterialApp widget (those widgets introduce
I/flutter (13775): a MediaQuery), or it can happen if the context you use comes from a widget above those widgets.

With the MediaQuery class and its data property, I would like to condition the textScaleFactor for the whole application, however I can not get a context before a MaterialApp...

So I don't want to go for each page I have adding the class like parent, how could I can add the class only once for the whole application?

LoginPage (it works but i don't want this)

final query = MediaQuery.of(context);

return MediaQuery(
  data: query.copyWith(textScaleFactor: 1.4),
  child: Scaffold(
     [...]
  );

Thank you,

2 Answers

The easiest is to wrap MaterialApp with another MaterialApp and set useInheritedMediaQuery:

    return MaterialApp(
      home: LayoutBuilder(
        builder: (context, _) { # builder so we can access MaterialApp context
          final query = MediaQuery.of(context);
          return MediaQuery(
              data: query.copyWith(textScaleFactor: 1.4),
              child: MaterialApp( 
                  useInheritedMediaQuery: true, #inherited MediaQuery will be used
                  ....

Another way is to use WidgetsBinding.instance.window.physicalSize https://stackoverflow.com/a/60415290/4679965

After a while, I was able to solve it in the following way without using another MaterialApp or WidgetsApp.

      MaterialApp(
        debugShowCheckedModeBanner: false,
        navigatorKey: navigatorKey, // here
        onGenerateRoute: RouteGenerator.generateRoute,
        [...]
        builder: (BuildContext context, Widget? child) => MediaQuery(
          data: MediaQuery.of(context).copyWith(
            textScaleFactor: MediaQuery.of(context)
                .textScaleFactor
                .clamp(1.0, 1.4),
          ),
          child: child ?? const SizedBox.shrink(),
        ),
      ),

Create a global variable in my route generator file and only call it in the app material

[...]
import 'package:flutter/material.dart';

final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

class RouteGenerator {
[...]
Related