Ошибка флаттера: вызов MediaQuery.of() с контекстом, который не содержит MediaQuery

Я пытался получить размер всего контекстного представления во Флаттере. Но каждый раз, когда я пытаюсь, я получаю вышеупомянутую ошибку. Вот мой код:

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. Пожалуйста, помогите мне найти, что я делаю не так здесь.

Ответы

Ответ 1

Вам нужен MaterialApp или WidgetsApp вокруг вашего виджета. Они предоставляют 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: ...,
    );
  }
}

Ответ 2

Вы можете получить доступ к 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 который имеет статический размер, чтобы вы могли использовать его во всем приложении.

Ответ 3

Я исправил это, используя следующий метод. Сначала я создал новый класс с именем MyWidget и возвратил его в MyApp в home: MyWidget 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(),
    );
  }
} 

Кроме того, объявление размера как окончательного значения не имеет значения. Ориентация/Поворот обрабатывается.

Ответ 4

Оберните ваш код в виджет приложения материалов. У меня тоже была такая же проблема, как я забыл ее использовать и напрямую вернул эшафот.

Другими словами, ваш MediaQuery.of(context) должен быть внутри виджета материала. Материал приложения → строительные леса → MediaQuery.of (контекст)

Ответ 5

Есть лучший способ. Приведенные выше решения потребуют от вас иметь только один экранный виджет или наследовать все экраны от родительского класса. Но есть решение, поместите инициализацию медиазапроса в функцию обратного вызова 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;
    }
}

Предупреждение. Это не копия & вставьте код, есть некоторые синглтоны и т.д., но вы должны понять суть;)

Ответ 6

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

Ответ 7

Здесь вы можете проверить свои решения.

 import 'package:flutter/material.dart';

 void main(){

    runApp(MyApp());
 }
 class MyApp extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return MaterialApp(
     title: "MediaQuery",
     home: Home(),
     );
   }
 }
 class Home extends StatefulWidget {
   @override
  _HomeState createState() => _HomeState();
 }

 class _HomeState extends State<Home> {
    @override
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
       title: Text("MediaQuery Solution"),
  ),
  body: Column(

    children: <Widget>[
      Container(
        height: (MediaQuery.of(context).size.height) / 2,
        width: (MediaQuery.of(context).size.width),
        color: Colors.red,
      )
     ],
    ),
   );
  }
 }

Ответ 8

Добавить MaterialApp...

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