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


76

我一直在尝试在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。请帮助我在这里找到我在做错什么。


您如何显示页面?
君特Zöchbauer

void main()=> runApp(new MyIntroductionPage());
科学怪人

您可以显示确切的错误吗?PS:不要保留最终尺寸,因为旋转手机时尺寸可能会改变。
阿诺德·帕奇

1
@ArnoldParge标题本身给出了确切的错误。
科学怪人

Answers:


97

您需要在小部件周围添加MaterialAppWidgetsApp。他们提供了MediaQuery。当您调用.of(context)flutter时,将始终查找窗口小部件树以找到窗口小部件。

您通常在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: ...,
    );
  }
}

我刚刚看到了您的修改。当您调用MediaQuery.of(context)时,MaterialApp必须已经在小部件3中。
伊恩

我遇到了同样的问题,但是在第一次运行中,我遇到了这个错误,第二次运行,并且可以正常运行。
Mohammad Meshkani

遇到与@MohammadMeshkani提到的相同的问题,错误在第二轮消失
chunhhanhan

我仍然有这个问题。
埃蒙

18

MediaQuery当您在里面时,您可以访问MaterialApp。您访问媒体查询的位置不正确。

请参考以下代码:

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

我特意创建了一个CommonThings具有静态Size的类,以便您可以在整个应用程序中使用它。


13

我使用以下方法修复了它。首先,我创建了一个名为新类MyWidget,并在它返回MyApp一个范围内MaterialApphome:。参考下面的代码:

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

另外,将大小声明为final并不重要。方向/旋转被处理。


多么奇怪的行为。使用WidgetsBinding.instance.window.physicalSize代替
Mikhail Baynov

10

在设置MaterialApp的主题时,也可以使用WidgetsBinding.instance.window而不是MediaQuery来实现我们的目的:

_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;

两种不同的结果WidgetsBinding.instance.window.padding.topMediaQuery.of(context).padding.top;
BloodLoss

@derChris非常感谢。这对我很好。:D
Chetan Goyal

@BloodLoss您可以WidgetsBinding.instance.window.viewPadding代替使用
intraector

8

通过重新运行应用程序解决(在android studio中单击“停止”按钮,然后再次运行)


4

更好的办法。上述解决方案将只需要一个屏幕小部件从父类继承所有屏幕。但是有解决方案,将媒体查询初始化放入onGenerateRoute回调函数中

主镖

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

警告:这不是复制和粘贴代码,有一些单例等,但您应该明白这一点;)


4

在发生相同的错误

import 'screens/tasks_screen.dart';

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

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

  }
}

我通过以下方法解决了:

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

3

将代码包装在Material App小部件中。我也遇到了同样的问题,因为我忘记了使用它并直接退回了脚手架。

换句话说,您的MediaQuery.of(context)应该在Material Widget中。材质应用->支架-> MediaQuery.of(上下文)


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

2

MediaQueryScaffold从其源代码可以明显看出,内部组件使用它来布局其子级。因此,需要将其包装在小部件内,该小部件将提供一个继承自MediaQueryMaterialApp小部件,例如小部件WidgetsApp

要修复您的MediaQuery.of(context),应在Material Widget中。材质应用->支架-> MediaQuery.of(上下文)

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Loading Page',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyAppPage(),
    );
  }
}

详细信息:使用不包含MediaQuery的上下文调用MediaQuery.of()



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

}

您应该尝试执行此操作。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.