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.


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

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.


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.


8

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


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;

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


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

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)


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

1

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


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



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.


-1

MaterialApp hinzufügen ...

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.