У меня тоже была эта проблема, и сначала я подумал, что MediaQuery вызывает ненужные перестройки, но если вы думаете об этом, вы действительно хотите, чтобы виджеты перестраивались (в случаях вращения устройства, всплывающая клавиатура), чтобы приложение имело отзывчивый дизайн.
Вы можете сделать что-то вроде этого:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Builder(builder: (context) {
ResponsiveApp.setMq(context);
return MyHomePage(title: 'Flutter Demo Home Page');
}),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Flex(
direction:
ResponsiveApp().mq.size.width > ResponsiveApp().mq.size.height
? Axis.horizontal
: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class ResponsiveApp {
static MediaQueryData _mediaQueryData;
MediaQueryData get mq => _mediaQueryData;
static void setMq(BuildContext context) {
_mediaQueryData = MediaQuery.of(context);
}
}
Я установил mediaQueryData в начале с ResponsiveApp.setMq(context)
и использовал Builder, потому что вы можете использовать только MediaQuery one context
под виджетом MaterialApp
. После установки _mediaQueryData
вы можете получить его, когда захотите создавать виджеты на основе размера экрана.
В этом коде я просто меняю направление оси, когда устройство поворачивается, и виджету необходимо перестроить, чтобы показать измененное направление.
У вас также может быть что-то вроде:
if (_mediaQueryData.size.shortestSide < 400)
//phone layout
else if(_mediaQueryData.size.shortestSide >= 400 && _mediaQueryData.size.shortestSide < 600)
//tablet layout
else
//web layout
а изменение размера окна в сети приведет к многократной перестройке виджетов и отображению желаемого макета.
Но если вы вообще не хотите использовать MediaQuery
, вы можете проверить класс Window из dart:ui
.
person
Calvin Gonsalves
schedule
14.01.2021