Flatterfehler: MediaQuery.of () wird mit einem Kontext aufgerufen, der keine MediaQuery enthält

74

Ich habe versucht, die Größe der gesamten Kontextansicht in Flutter zu ermitteln. Aber jedes Mal, wenn ich es versuche, erhalte ich den oben genannten Fehler. Hier ist mein Code:

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

Hinweis: Ich habe es auch mit einem versucht StatefulWidget. Bitte helfen Sie mir herauszufinden, was ich hier falsch mache.

Frankenstein
quelle
Wie zeigen Sie die Seite?
Günter Zöchbauer
void main () => runApp (neue MyIntroductionPage ());
Frankenstein
Können Sie den genauen Fehler anzeigen? PS: Behalten Sie die Größe nicht als endgültig bei, da sie sich ändern kann, wenn Sie das Telefon drehen.
Arnold Parge
1
@ArnoldParge Der genaue Fehler ist im Titel selbst angegeben.
Frankenstein

Antworten:

91

Sie benötigen ein MaterialAppoder ein WidgetsAppum Ihr Widget. Sie bieten die MediaQuery. Wenn Sie .of(context)Flutter aufrufen, wird immer der Widget-Baum nachgeschlagen, um das Widget zu finden.

Normalerweise haben Sie dies in Ihrem 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: ...,
    );
  }
}
Ian
quelle
Ich habe gerade Ihre Änderungen gesehen. Wenn Sie MediaQuery.of (Kontext) aufrufen, muss sich die MaterialApp bereits im Widget 3 befinden.
Ian
Ich hatte das gleiche Problem, aber gerade im ersten Lauf hatte ich diesen Fehler und im zweiten Lauf und mehr funktioniert richtig.
Mohammad Meshkani
Stieß auf die gleiche Frage wie @MohammadMeshkani erwähnt, verschwinden Fehler beim zweiten Lauf
Chunhunghan
Trotzdem habe ich dieses Problem.
Emon
17

Sie können zugreifen, MediaQuerywenn Sie drinnen sind MaterialApp. Der Ort, an dem Sie auf die Medienabfrage zugreifen, ist nicht korrekt.

Bitte beziehen Sie sich auf den folgenden 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();
  }
}

Ich habe absichtlich eine Klasse CommonThingsmit statischer Größe erstellt, damit Sie sie in der gesamten App verwenden können.

Arnold Parge
quelle
11

Ich habe es mit der folgenden Methode behoben. Zuerst habe ich eine neue Klasse mit dem Namen erstellt MyWidgetund sie MyAppinnerhalb von a MaterialApp's zurückgegeben home:. Siehe Code unten:

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

Außerdem spielt es keine Rolle, die Größe als endgültig zu deklarieren. Orientierung / Drehung wird behandelt.

Frankenstein
quelle
8

Gelöst durch erneutes Ausführen der App (klicken Sie in Android Studio auf die Schaltfläche Stopp und dann erneut ausführen)

user3374790
quelle
6

Was für uns funktioniert, ist die Verwendung von WidgetsBinding.instance.window anstelle von MediaQuery - auch beim Festlegen des Themas der 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;
derChris
quelle
zwei unterschiedliche Ergebnisse in WidgetsBinding.instance.window.padding.topundMediaQuery.of(context).padding.top;
BloodLoss
@derChris vielen Dank. Es hat gut für mich funktioniert. : D
Harsh Aggarwal
3

Es gibt einen besseren Weg . Bei den oben genannten Lösungen müssen Sie nur ein Bildschirm-Widget haben oder alle Bildschirme von der übergeordneten Klasse erben . Es gibt jedoch eine Lösung : Platzieren Sie die Initialisierung der Medienabfrage in der Rückruffunktion 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;
    }
}

Warnung: Es ist kein Code zum Kopieren und Einfügen, es gibt einige Singletons usw., aber Sie sollten den Punkt verstehen;)

Srneczek
quelle
3

Hatte den gleichen Fehler in

import 'screens/tasks_screen.dart';

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

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

  }
}

Ich habe es gelöst durch: -

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

Wickeln Sie Ihren Code in ein Material App-Widget. Ich hatte auch das gleiche Problem, als ich vergaß, es zu benutzen, und gab das Gerüst direkt zurück.

Mit anderen Worten, Ihre MediaQuery.of (Kontext) sollte sich im Material Widget befinden. Material App -> Gerüst -> MediaQuery.of (Kontext)

Mahi
quelle
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(
    );
  }
}
Shubhanshu Singh
quelle
1

Mit anderen Worten, Ihre MediaQuery.of (Kontext) sollte sich im Material Widget befinden. Material App -> Gerüst -> MediaQuery.of (Kontext)

Kayson
quelle
1

MediaQuerywird von Scaffoldinternen Komponenten verwendet, um die untergeordneten Elemente so zu gestalten, wie dies aus dem Quellcode hervorgeht . So muss es in einem Widget gewickelt werden , die ein liefern wird MediaQuery, wie ein MaterialAppWidget, das von erbt WidgetsApp.

Um Ihre MediaQuery.of (Kontext) zu reparieren, sollte sich im Material Widget befinden. Material App -> Gerüst -> MediaQuery.of (Kontext)

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

Weitere Informationen : MediaQuery.of () wird mit einem Kontext aufgerufen, der keine MediaQuery enthält

Paresh Mangukiya
quelle
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,
        
    );
  }

}

Sie sollten versuchen, dass ich es getan habe.

Rishabh Gupta
quelle
-1

MaterialApp hinzufügen ...

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

Antonio Rabelo
quelle