Ошибка флаттера: вызов 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(), )); }