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

时间:2018-05-07 12:32:59

标签: dart flutter

我一直试图在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。 请帮助我找到我在这里做错的事。

14 个答案:

答案 0 :(得分:18)

您的小部件周围需要MaterialAppWidgetsApp。他们提供MediaQuery。当您致电.of(context)时,颤动将始终查找小部件树以查找小部件。

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

答案 1 :(得分:9)

对我们有用的是使用WidgetsBinding.instance.window而不是MediaQuery-也在设置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;

答案 2 :(得分: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 :(得分:3)

您在for attr, attr_d in correlations.items(): for correl, correl_d in attr_d.items(): for split, split_d in correl_d.items(): results_df.query(f"correlator == {correl} and expertise == {split} and coeff_p == 'p'")[attr] = split_d['p'] results_df.query(f"correlator == {correl} and expertise == {split} and coeff_p != 'p'")[attr] = split_d['r'] if 'r' in split_d else split_d['rho'] if 'rho' in split_d else split['tau'] > pandas.core.computation.ops.UndefinedVariableError: name 'pearson' is not defined 内时可以访问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(); } } ,以便您可以在整个应用中使用它。

答案 4 :(得分:2)

我使用以下方法修复它。首先,我创建了一个名为MyWidget的新类,并在MyApp MaterialApp内的home:中将其返回。请参考以下代码:

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

另外,将尺寸声明为最终尺寸并不重要。处理方向/旋转。

答案 5 :(得分:2)

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

答案 6 :(得分:2)

source code可以明显看出,MediaQuery内部组件使用

Scaffold来布局其子级。因此,需要将其包装在提供MediaQuery小部件的小部件内,就像MaterialApp小部件一样,其继承自WidgetsApp

要修复您的MediaQuery.of(context)应该位于Material Widget内。材质应用->支架-> MediaQuery.of(context)

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.of() called with a context that does not contain a MediaQuery

答案 7 :(得分:1)

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

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

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

答案 8 :(得分:1)

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

答案 9 :(得分:1)

换句话说,您的MediaQuery.of(context)应该位于Material Widget内。材质应用->支架-> MediaQuery.of(context)

答案 10 :(得分:0)

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

换句话说,您的MediaQuery.of(context)应该位于Material Widget内。 材质应用->支架-> MediaQuery.of(context)

答案 11 :(得分:0)

我试图更改包装,然后出现此错误, 因此,请确保您完成以下每个步骤

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

答案 12 :(得分: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,
        
    );
  }

}

您应该尝试执行此操作。

答案 13 :(得分:-2)

添加MaterialApp ...

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