How to Solve MediaQuery.of() Called With a Context that does not Contain a MediaQuery ??

· 5 min read
How to Solve MediaQuery.of() Called With a Context that does not Contain a MediaQuery
How to Solve MediaQuery.of() Called With a Context that does not Contain a MediaQuery

MediaQuery Widget is the first place you should look if you’re trying to get specific information about the physical device your app is running on, or if you want to manipulate the device. So, in this article, we will go through how to solve MediaQuery.of() Called With a Context that does not contain a MediaQuery.

How to Solve MediaQuery.of() Called With a Context that does not Contain a MediaQuery ??

What is MediaQuery Widget in Flutter ?

The MediaQuery Widget is a widget similar to Theme in that you can use the BuildContext to access it anywhere in the app.

This is done via a method on the MediaQuery class called off.

So the method will look up the tree, find the nearest MediaQuery class, and give you a reference to that MediaQuery instance anywhere in your app.

A few widgets built into Flutter provide an of the method.

You need a MaterialApp Widget or a WidgetsApp around your widget. They provide MediaQuery. When you call .of(context) flutter will always look up the widget tree to find the widget.

So the code snippet will look like the below:

void main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Title',
      theme: kThemeData,
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;

    return Container(
      child: ...,
    );
  }
}

You can access MediaQuery when you are inside MaterialApp.

The place where you are accessing the media query is not correct. Please refer to the code below:

import 'package:flutter/material.dart';

class CommonThings {
  static Size size;
}

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'MediaQuery Demo',
      theme: new ThemeData(
        primarySwatch: Colors.red,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    CommonThings.size = MediaQuery.of(context).size;
    print('Width of the screen: ${CommonThings.size.width}');
    return new Container();
  }
}

So the above solutions would require you to have only one screen widget or inherit all screens from the parent class.

But there is the solution, place the media query initialization into the onGenerateRoute callback function

main.dart

import 'package:flutter/material.dart';

class MyApp extends StatefulWidget {
    @override
    State<StatefulWidget> createState() => new MyAppState();
}

class MyAppState extends State<MyApp> {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'My Awesome App',
        routes: NavigationUtils.routeList(),
        onGenerateRoute: (routeSettings) =>
          NavigationUtils.onGenerateRoute(routeSettings),
      );
    }
}

NavigationUtils.dart

import 'package:flutter/material.dart';

class NavigationUtils {
    static onGenerateRoute(RouteSettings routeSettings) {   
      return new MaterialPageRoute(
        builder: (context) {
          WidgetUtils.me.init(context);
            return StorageUtils.me.isLogged() ? HomeScreen() : ForkScreen();
        },
        settings: routeSettings,
      );
    }
}

WidgetUtils.dart

import 'package:flutter/material.dart';

class WidgetUtils {
    MediaQueryData _mediaQueryData;
    double _screenWidth;
    double _screenHeight;
    double _blockSizeHorizontal;
    double _blockSizeVertical;

    init(BuildContext context) {
        _mediaQueryData = MediaQuery.of(context);
        screenWidth = _mediaQueryData.size.width;
        screenHeight = _mediaQueryData.size.height;
        blockSizeHorizontal = screenWidth / 100;
        blockSizeVertical = screenHeight / 100;
    }
}

You can also try with below code snippet.

import 'package:flutter/material.dart';
import 'screens/tasks_screen.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TasksScreen(),
    );
  }
}

So MediaQuery is used by Scaffold internal components to layout its children as evident from its source code.

Thus, it needs to be wrapped inside a widget that will provide a MediaQuery, like a MaterialApp widget, which inherits from WidgetsApp.

Conclusion:

So in this article, we have learned how to solve MediaQuery.of() Called With a Context that does not contain a MediaQuery.

Tell us in the comments what methods you use for the same!!

Keep Learning !!! Keep Fluttering !!!

Do let us know in the comments if you are still confused in flutter!!

FlutterAgency.com is our portal Platform dedicated to Flutter Technology and Flutter Developers. The portal is full of cool resources from Flutter like Flutter Widget GuideFlutter ProjectsCode libs and etc.

FlutterAgency.com is one of the most popular online portals dedicated to Flutter Technology and daily thousands of unique visitors come to this portal to enhance their knowledge of Flutter.

Leave a Reply