Flutter Error: 使用不包含 MediaQuery 的上下文调用 MediaQuery.of()

我一直试图了解 Flutter 整个背景的规模。但是每次尝试都会得到上面提到的错误。 这是我的密码:

import 'package:flutter/material.dart';


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


class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {


final size = MediaQuery.of(context).size;
return new MaterialApp(
home: new Scaffold(),
);
}
}

注意: 我也试过使用 StatefulWidget。 求你了,帮我找出我做错了什么。

100200 次浏览

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

You usually have this in your main.dart:

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 below code:

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();
}
}

I've purposely created a class CommonThings which has static Size so that you can use it throughout the app.

I fixed it by using the following method. First I created a new class named MyWidget and returned it in MyApp within a MaterialApp's home:. Refer code below:

import 'package:flutter/material.dart';


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


class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {


return new MaterialApp(
home: new MyWidget(),
);
}
}


class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {


final size = MediaQuery.of(context).size;
return new MaterialApp(
home: new Scaffold(),
);
}
}

Also, declaring size as final doesn't matter. Orientation/Rotation is handled.

Add MaterialApp ...

void main() {
runApp(MaterialApp(
home: HomePage(),
));
}

Wrap your code in a Material App widget. I also had the same issue as I forgot to use it and directly returned the scaffold.

In other words, your MediaQuery.of(context) should be inside the Material Widget. Material app -> scaffold -> MediaQuery.of(context)

There is better way. Above solutions would require you to have only one screen widget or inherit all screens from parent class. But there is solution, place the media query initialization into 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;
}
}

Warning: It is not copy & paste code, there are some singletons etc. but you should get the point ;)

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


class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyAppOne(),
);
}
}
class MyAppOne extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyAppOne>{
@override
Widget build(BuildContext context){
return Scaffold(
);
}
}

Solved by re-run the app(click on stop button in android studio then run again)

Had the same error in

import 'screens/tasks_screen.dart';


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


class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TasksScreen();


}
}

I solved it by:-

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(),
);
}
}

What works for us is using WidgetsBinding.instance.window instead of MediaQuery - also when setting the theme of the MaterialApp:

_pixelRatio = WidgetsBinding.instance.window.devicePixelRatio;
_screenWidth = WidgetsBinding.instance.window.physicalSize.width;
_screenHeight = WidgetsBinding.instance.window.physicalSize.height;
_statusBarHeight = WidgetsBinding.instance.window.padding.top;
_bottomBarHeight = WidgetsBinding.instance.window.padding.bottom;
_textScaleFactor = WidgetsBinding.instance.window.textScaleFactor;

I was trying to change the package then this error arise, so make sure you complete each of the following steps

https://stackoverflow.com/a/51550358/4993045

import 'package:flutter/material.dart';


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


class App extends StatelessWidget {


@override
 

Widget build(BuildContext context) {
    

return MaterialApp(
    

home: Scaffold(
body:HomePage(),
),
);
}


}




class HomePage extends StatelessWidget {


@override


Widget build(BuildContext context) {


var size = MediaQuery.of(context).size.height;


return Container(
height:size/2,
color:Colors.lightBlueAccent,
        

);
}


}

YOU SHOULD TRY THIS I HAVE DONE IT.