Я столкнулся с трудностями, чтобы заставить его реагировать на различные размеры экрана. Как сделать отзывчивым?
@override
Widget build(BuildContext context) {
return new Container(
decoration: new BoxDecoration(color: Colors.white),
child: new Stack(
children: [
new Padding(
padding: const EdgeInsets.only(bottom: 350.0),
child: new GradientAppBar(" "),
),
new Positioned(
bottom: 150.0,
height: 260.0,
left: 10.0,
right: 10.0,
child: new Padding(
padding: new EdgeInsets.all(10.0),
child: new Card(
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const ListTile(
title: const Text(
'LOGIN',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 16.50,
fontFamily: "Helvetica",
fontWeight: FontWeight.bold,
color: Colors.black87,
letterSpacing: 1.00,
),
),
),
new ListTile(
leading: const Icon(Icons.person),
title: new TextField(
controller: _user1,
decoration: new InputDecoration(
labelText: ' Enter a username'),
),
),
new ListTile(
leading: const Icon(Icons.person_pin),
title: new TextField(
controller: _pass1,
decoration: new InputDecoration(
labelText: ' Enter a password'),
obscureText: true,
),
),
],
),
),
),
),
new Positioned(
bottom: 70.0,
left: 15.0,
right: 05.0,
child: new ButtonTheme.bar(
// make buttons use the appropriate styles for cards
child: new ButtonBar(
children: <Widget>[
new FlatButton(
padding: new EdgeInsets.only(right: 13.0),
child: new Text(
'REGISTER HERE',
style: new TextStyle(
color: Colors.black87,
fontFamily: "Helvetica",
fontSize: 15.00,
fontWeight: FontWeight.bold),
),
onPressed: () {
Navigator.of(context).pushNamed('/facebook');
},
),
new FlatButton(
padding: new EdgeInsets.only(right: 22.0),
child: new Text(
'FORGOT PASSWORD?',
style: new TextStyle(
color: Colors.black87,
fontFamily: "Helvetica",
fontSize: 15.00,
fontWeight: FontWeight.bold),
),
onPressed: () {
Navigator.of(context).pushNamed('/Forgot');
},
),
],
),
),
),
new Positioned(
bottom: 73.0,
height: 180.0,
left: 20.0,
right: 52.0,
child: new Padding(
padding: new EdgeInsets.all(0.00),
child: new ButtonTheme(
minWidth: 10.0,
height: 20.0,
padding: new EdgeInsets.only(right: 37.0),
child: new ButtonBar(children: <Widget>[
new CupertinoButton(
borderRadius:
const BorderRadius.all(const Radius.circular(36.0)),
padding: new EdgeInsets.only(left: 70.0),
color: const Color(0xFF426DB7),
child: new Text(
" LOGIN ",
style: new TextStyle(
color: Colors.white,
fontSize: 12.50,
fontFamily: "Handwriting",
fontWeight: FontWeight.w500,
letterSpacing: 0.00),
),
onPressed: () {})
]),
),
),
),
],
),
);
}
}
MediaQuery
достаточно. Возможно, вы захотите это проверить.Ответы:
Использование
MediaQuery
класса:Чтобы получить соотношение пикселей устройства:
Чтобы получить ширину и высоту экрана устройства:
Чтобы получить коэффициент масштабирования текста:
Использование
AspectRatio
класса:Из документа:
//example new Center( child: new AspectRatio( aspectRatio: 100 / 100, child: new Container( decoration: new BoxDecoration( shape: BoxShape.rectangle, color: Colors.orange, ) ), ), ),
Также вы можете использовать :
источник
queryData
.Этот класс поможет, а затем инициализирует класс с помощью метода init.
import 'package:flutter/widgets.dart'; class SizeConfig { static MediaQueryData _mediaQueryData; static double screenWidth; static double screenHeight; static double blockSizeHorizontal; static double blockSizeVertical; static double _safeAreaHorizontal; static double _safeAreaVertical; static double safeBlockHorizontal; static double safeBlockVertical; void init(BuildContext context){ _mediaQueryData = MediaQuery.of(context); screenWidth = _mediaQueryData.size.width; screenHeight = _mediaQueryData.size.height; blockSizeHorizontal = screenWidth/100; blockSizeVertical = screenHeight/100; _safeAreaHorizontal = _mediaQueryData.padding.left + _mediaQueryData.padding.right; _safeAreaVertical = _mediaQueryData.padding.top + _mediaQueryData.padding.bottom; safeBlockHorizontal = (screenWidth - _safeAreaHorizontal)/100; safeBlockVertical = (screenHeight - _safeAreaVertical)/100; } }
тогда в вашем измерении виджетов сделайте это
Widget build(BuildContext context) { SizeConfig().init(context); return Container( height: SizeConfig.safeBlockVertical * 10, //10 for example width: SizeConfig.safeBlockHorizontal * 10, //10 for example );}
Все кредиты автору этого сообщения: https://medium.com/flutter-community/flutter-effectively-scale-ui-according-to-different-screen-sizes-2cb7c115ea0a
источник
Что я делаю, так это беру ширину и высоту экрана и вычисляю из нее сетку 100 * 100, чтобы позиционировать и масштабировать объекты и сохранять ее как статические переменные, которые можно использовать повторно. В большинстве случаев работает неплохо. Как это:
AppConfig.width = MediaQuery.of(context).size.width; AppConfig.height = MediaQuery.of(context).size.height; AppConfig.blockSize = AppConfig.width / 100; AppConfig.blockSizeVertical = AppConfig.height / 100;
Затем я масштабирую все в соответствии с этими значениями, например:
double elementWidth = AppConfig.blockSize * 10.0; // 10% of the screen width
или же
double fontSize = AppConfig.blockSize * 1.2;
Иногда безопасная область (выемка и т. Д.) Убивает макет, поэтому вы тоже можете это учитывать:
AppConfig.safeAreaHorizontal = MediaQuery.of(context).padding.left + MediaQuery.of(context).padding.right; double screenWidthWithoutSafeArea = AppConfig.width - AppConfig.safeAreaHorizontal;
Это отлично сработало в некоторых недавних проектах.
источник
Проверить
MediaQuery
классИтак, вы можете сделать следующее:
new Container( height: MediaQuery.of(context).size.height/2, .. )
источник
Самый простой способ сделать пользовательский интерфейс адаптивным для экрана разного размера - это плагин Sizer .
Сделайте отзывчивый пользовательский интерфейс на устройстве любого размера, включая планшет. Проверить это плагин ⬇️
https://pub.dev/packages/sizer
.h - for widget height .w - for widget width .sp - for font size
Используйте
.h
,.w
,.sp
после значения , как это ⬇️Пример:
Container( height: 10.0.h, //10% of screen height width: 80.0.w, //80% of screen width child: Text('Sizer', style: TextStyle(fontSize: 12.0.sp)), );
С помощью этого плагина я создал множество адаптивных приложений.
источник
Вы можете взять процент от ширины или высоты в качестве входных данных для размера шкалы.
fontSize: MediaQuery.of(_ctxt).size.height * 0.065
Где множитель в конце имеет значение, благодаря которому текст выглядит хорошо для активного эмулятора.
Ниже я настроил его так, чтобы все масштабированные размеры были централизованы в одном месте. Таким образом, вы можете легко настроить их и быстро перезапустить с помощью Hot Reload без необходимости искать
Media.of()
вызовы по всему коду.class AppScale { BuildContext _ctxt; AppScale(this._ctxt); double get labelDim => scaledWidth(.04); double get popupMenuButton => scaledHeight(.065); double scaledWidth(double widthScale) { return MediaQuery.of(_ctxt).size.width * widthScale; } double scaledHeight(double heightScale) { return MediaQuery.of(_ctxt).size.height * heightScale; } }
AppScale _scale = AppScale(context); // ... Widget label1 = Text( "Some Label", style: TextStyle(fontSize: _scale.labelDim), );
Благодаря ответам в этом посте
источник
Place dependency in pubspec.yaml flutter_responsive_screen: ^1.0.0 Function hp = Screen(MediaQuery.of(context).size).hp; Function wp = Screen(MediaQuery.of(context).size).wp; Example : return Container(height: hp(27),weight: wp(27));
источник
После долгих исследований и испытаний я разработал решение для приложения, которое сейчас конвертирую с Android / iOS на Flutter.
В Android и iOS я использовал «коэффициент масштабирования», применяемый к базовым размерам шрифтов, визуализируя размеры текста, которые были связаны с размером экрана.
Эта статья была очень полезной: https://medium.com/flutter-community/flutter-effectively-scale-ui-according-to-different-screen-sizes-2cb7c115ea0a
Я создал StatelessWidget, чтобы получить размеры шрифта типографских стилей Material Design. Получение размеров устройства с помощью MediaQuery, вычисление коэффициента масштабирования, а затем сброс размеров текста в Material Design. Виджет можно использовать для определения пользовательской темы дизайна материалов.
Используемые эмуляторы:
Со стандартными размерами шрифта
С масштабированными размерами шрифта
set_app_theme.dart (виджет SetAppTheme)
import 'package:flutter/material.dart'; import 'dart:math'; class SetAppTheme extends StatelessWidget { final Widget child; SetAppTheme({this.child}); @override Widget build(BuildContext context) { final _divisor = 400.0; final MediaQueryData _mediaQueryData = MediaQuery.of(context); final _screenWidth = _mediaQueryData.size.width; final _factorHorizontal = _screenWidth / _divisor; final _screenHeight = _mediaQueryData.size.height; final _factorVertical = _screenHeight / _divisor; final _textScalingFactor = min(_factorVertical, _factorHorizontal); final _safeAreaHorizontal = _mediaQueryData.padding.left + _mediaQueryData.padding.right; final _safeFactorHorizontal = (_screenWidth - _safeAreaHorizontal) / _divisor; final _safeAreaVertical = _mediaQueryData.padding.top + _mediaQueryData.padding.bottom; final _safeFactorVertical = (_screenHeight - _safeAreaVertical) / _divisor; final _safeAreaTextScalingFactor = min(_safeFactorHorizontal, _safeFactorHorizontal); print('Screen Scaling Values:' + '_screenWidth: $_screenWidth'); print('Screen Scaling Values:' + '_factorHorizontal: $_factorHorizontal '); print('Screen Scaling Values:' + '_screenHeight: $_screenHeight'); print('Screen Scaling Values:' + '_factorVertical: $_factorVertical '); print('_textScalingFactor: $_textScalingFactor '); print('Screen Scaling Values:' + '_safeAreaHorizontal: $_safeAreaHorizontal '); print('Screen Scaling Values:' + '_safeFactorHorizontal: $_safeFactorHorizontal '); print('Screen Scaling Values:' + '_safeAreaVertical: $_safeAreaVertical '); print('Screen Scaling Values:' + '_safeFactorVertical: $_safeFactorVertical '); print('_safeAreaTextScalingFactor: $_safeAreaTextScalingFactor '); print('Default Material Design Text Themes'); print('display4: ${Theme.of(context).textTheme.display4}'); print('display3: ${Theme.of(context).textTheme.display3}'); print('display2: ${Theme.of(context).textTheme.display2}'); print('display1: ${Theme.of(context).textTheme.display1}'); print('headline: ${Theme.of(context).textTheme.headline}'); print('title: ${Theme.of(context).textTheme.title}'); print('subtitle: ${Theme.of(context).textTheme.subtitle}'); print('body2: ${Theme.of(context).textTheme.body2}'); print('body1: ${Theme.of(context).textTheme.body1}'); print('caption: ${Theme.of(context).textTheme.caption}'); print('button: ${Theme.of(context).textTheme.button}'); TextScalingFactors _textScalingFactors = TextScalingFactors( display4ScaledSize: (Theme.of(context).textTheme.display4.fontSize * _safeAreaTextScalingFactor), display3ScaledSize: (Theme.of(context).textTheme.display3.fontSize * _safeAreaTextScalingFactor), display2ScaledSize: (Theme.of(context).textTheme.display2.fontSize * _safeAreaTextScalingFactor), display1ScaledSize: (Theme.of(context).textTheme.display1.fontSize * _safeAreaTextScalingFactor), headlineScaledSize: (Theme.of(context).textTheme.headline.fontSize * _safeAreaTextScalingFactor), titleScaledSize: (Theme.of(context).textTheme.title.fontSize * _safeAreaTextScalingFactor), subtitleScaledSize: (Theme.of(context).textTheme.subtitle.fontSize * _safeAreaTextScalingFactor), body2ScaledSize: (Theme.of(context).textTheme.body2.fontSize * _safeAreaTextScalingFactor), body1ScaledSize: (Theme.of(context).textTheme.body1.fontSize * _safeAreaTextScalingFactor), captionScaledSize: (Theme.of(context).textTheme.caption.fontSize * _safeAreaTextScalingFactor), buttonScaledSize: (Theme.of(context).textTheme.button.fontSize * _safeAreaTextScalingFactor)); return Theme( child: child, data: _buildAppTheme(_textScalingFactors), ); } } final ThemeData customTheme = ThemeData( primarySwatch: appColorSwatch, // fontFamily: x, ); final MaterialColor appColorSwatch = MaterialColor(0xFF3787AD, appSwatchColors); Map<int, Color> appSwatchColors = { 50 : Color(0xFFE3F5F8), 100 : Color(0xFFB8E4ED), 200 : Color(0xFF8DD3E3), 300 : Color(0xFF6BC1D8), 400 : Color(0xFF56B4D2), 500 : Color(0xFF48A8CD), 600 : Color(0xFF419ABF), 700 : Color(0xFF3787AD), 800 : Color(0xFF337799), 900 : Color(0xFF285877), }; _buildAppTheme (TextScalingFactors textScalingFactors) { return customTheme.copyWith( accentColor: appColorSwatch[300], buttonTheme: customTheme.buttonTheme.copyWith(buttonColor: Colors.grey[500],), cardColor: Colors.white, errorColor: Colors.red, inputDecorationTheme: InputDecorationTheme(border: OutlineInputBorder(),), primaryColor: appColorSwatch[700], primaryIconTheme: customTheme.iconTheme.copyWith(color: appColorSwatch), scaffoldBackgroundColor: Colors.grey[100], textSelectionColor: appColorSwatch[300], textTheme: _buildAppTextTheme(customTheme.textTheme, textScalingFactors), appBarTheme: customTheme.appBarTheme.copyWith( textTheme: _buildAppTextTheme(customTheme.textTheme, textScalingFactors)), // accentColorBrightness: , // accentIconTheme: , // accentTextTheme: , // appBarTheme: , // applyElevationOverlayColor: , // backgroundColor: , // bannerTheme: , // bottomAppBarColor: , // bottomAppBarTheme: , // bottomSheetTheme: , // brightness: , // buttonBarTheme: , // buttonColor: , // canvasColor: , // cardTheme: , // chipTheme: , // colorScheme: , // cupertinoOverrideTheme: , // cursorColor: , // dialogBackgroundColor: , // dialogTheme: , // disabledColor: , // dividerColor: , // dividerTheme: , // floatingActionButtonTheme: , // focusColor: , // highlightColor: , // hintColor: , // hoverColor: , // iconTheme: , // indicatorColor: , // materialTapTargetSize: , // pageTransitionsTheme: , // platform: , // popupMenuTheme: , // primaryColorBrightness: , // primaryColorDark: , // primaryColorLight: , // primaryTextTheme: , // secondaryHeaderColor: , // selectedRowColor: , // sliderTheme: , // snackBarTheme: , // splashColor: , // splashFactory: , // tabBarTheme: , // textSelectionHandleColor: , // toggleableActiveColor: , // toggleButtonsTheme: , // tooltipTheme: , // typography: , // unselectedWidgetColor: , ); } class TextScalingFactors { final double display4ScaledSize; final double display3ScaledSize; final double display2ScaledSize; final double display1ScaledSize; final double headlineScaledSize; final double titleScaledSize; final double subtitleScaledSize; final double body2ScaledSize; final double body1ScaledSize; final double captionScaledSize; final double buttonScaledSize; TextScalingFactors({ @required this.display4ScaledSize, @required this.display3ScaledSize, @required this.display2ScaledSize, @required this.display1ScaledSize, @required this.headlineScaledSize, @required this.titleScaledSize, @required this.subtitleScaledSize, @required this.body2ScaledSize, @required this.body1ScaledSize, @required this.captionScaledSize, @required this.buttonScaledSize }); } TextTheme _buildAppTextTheme( TextTheme _customTextTheme, TextScalingFactors _scaledText) { return _customTextTheme.copyWith( display4: _customTextTheme.display4.copyWith(fontSize: _scaledText.display4ScaledSize), display3: _customTextTheme.display3.copyWith(fontSize: _scaledText.display3ScaledSize), display2: _customTextTheme.display2.copyWith(fontSize: _scaledText.display2ScaledSize), display1: _customTextTheme.display1.copyWith(fontSize: _scaledText.display1ScaledSize), headline: _customTextTheme.headline.copyWith(fontSize: _scaledText.headlineScaledSize), title: _customTextTheme.title.copyWith(fontSize: _scaledText.titleScaledSize), subtitle: _customTextTheme.subtitle.copyWith(fontSize: _scaledText.subtitleScaledSize), body2: _customTextTheme.body2.copyWith(fontSize: _scaledText.body2ScaledSize), body1: _customTextTheme.body1.copyWith(fontSize: _scaledText.body1ScaledSize), caption: _customTextTheme.caption.copyWith(fontSize: _scaledText.captionScaledSize), button: _customTextTheme.button.copyWith(fontSize: _scaledText.buttonScaledSize), ).apply(bodyColor: Colors.black); }
main.dart (демонстрационное приложение)
import 'package:flutter/material.dart'; import 'package:scaling/set_app_theme.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: SetAppTheme(child: HomePage()), ); } } class HomePage extends StatelessWidget { final demoText = '0123456789'; @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( appBar: AppBar( title: Text('Text Scaling with SetAppTheme', style: TextStyle(color: Colors.white),), ), body: SingleChildScrollView( child: Center( child: Padding( padding: const EdgeInsets.all(8.0), child: Column( children: <Widget>[ Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.display4.fontSize, ), ), Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.display3.fontSize, ), ), Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.display2.fontSize, ), ), Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.display1.fontSize, ), ), Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.headline.fontSize, ), ), Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.title.fontSize, ), ), Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.subtitle.fontSize, ), ), Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.body2.fontSize, ), ), Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.body1.fontSize, ), ), Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.caption.fontSize, ), ), Text( demoText, style: TextStyle( fontSize: Theme.of(context).textTheme.button.fontSize, ), ), ], ), ), ), ), ), ); } }
источник
Я здесь немного усложнял решения других людей (@datayeah & Vithani Ravi), поэтому я подумал, что поделюсь своей собственной попыткой (-ями) решить эту проблему масштабирования с переменной плотностью экрана или замолчу. Поэтому я подхожу к этой проблеме с твердой / фиксированной основы: я основываю все свое масштабирование на фиксированном (неизменном) соотношении 2: 1 (высота: ширина). У меня есть вспомогательный класс «McGyver», который выполняет всю тяжелую работу (и оптимизирует полезный код) в моем приложении. Этот класс «МакГайвер» содержит только статические методы и члены статических констант.
СПОСОБ МАСШТАБИРОВАНИЯ: Я масштабирую ширину и высоту независимо, исходя из соотношения сторон 2: 1. Я беру входные значения ширины и высоты и делю каждое на константы ширины и высоты и, наконец, вычисляю поправочный коэффициент, с помощью которого масштабируются соответствующие входные значения ширины и высоты. Фактический код выглядит следующим образом:
import 'dart:math'; import 'package:flutter/material.dart'; class McGyver { static const double _fixedWidth = 410; // Set to an Aspect Ratio of 2:1 (height:width) static const double _fixedHeight = 820; // Set to an Aspect Ratio of 2:1 (height:width) // Useful rounding method (@andyw solution -> /programming/28419255/how-do-you-round-a-double-in-dart-to-a-given-degree-of-precision-after-the-decim/53500405#53500405) static double roundToDecimals(double val, int decimalPlaces){ double mod = pow(10.0, decimalPlaces); return ((val * mod).round().toDouble() / mod); } // The 'Ratio-Scaled' Widget method (takes any generic widget and returns a "Ratio-Scaled Widget" - "rsWidget") static Widget rsWidget(BuildContext ctx, Widget inWidget, double percWidth, double percHeight) { // ---------------------------------------------------------------------------------------------- // // INFO: Ratio-Scaled "SizedBox" Widget - Scaling based on device's height & width at 2:1 ratio. // // ---------------------------------------------------------------------------------------------- // final int _decPlaces = 5; final double _fixedWidth = McGyver._fixedWidth; final double _fixedHeight = McGyver._fixedHeight; Size _scrnSize = MediaQuery.of(ctx).size; // Extracts Device Screen Parameters. double _scrnWidth = _scrnSize.width.floorToDouble(); // Extracts Device Screen maximum width. double _scrnHeight = _scrnSize.height.floorToDouble(); // Extracts Device Screen maximum height. double _rsWidth = 0; if (_scrnWidth == _fixedWidth) { // If input width matches fixedWidth then do normal scaling. _rsWidth = McGyver.roundToDecimals((_scrnWidth * (percWidth / 100)), _decPlaces); } else { // If input width !match fixedWidth then do adjustment factor scaling. double _scaleRatioWidth = McGyver.roundToDecimals((_scrnWidth / _fixedWidth), _decPlaces); double _scalerWidth = ((percWidth + log(percWidth + 1)) * pow(1, _scaleRatioWidth)) / 100; _rsWidth = McGyver.roundToDecimals((_scrnWidth * _scalerWidth), _decPlaces); } double _rsHeight = 0; if (_scrnHeight == _fixedHeight) { // If input height matches fixedHeight then do normal scaling. _rsHeight = McGyver.roundToDecimals((_scrnHeight * (percHeight / 100)), _decPlaces); } else { // If input height !match fixedHeight then do adjustment factor scaling. double _scaleRatioHeight = McGyver.roundToDecimals((_scrnHeight / _fixedHeight), _decPlaces); double _scalerHeight = ((percHeight + log(percHeight + 1)) * pow(1, _scaleRatioHeight)) / 100; _rsHeight = McGyver.roundToDecimals((_scrnHeight * _scalerHeight), _decPlaces); } // Finally, hand over Ratio-Scaled "SizedBox" widget to method call. return SizedBox( width: _rsWidth, height: _rsHeight, child: inWidget, ); } }
... ... ...
Затем вы индивидуально масштабируете свои виджеты (которые для моей болезни перфекционизма являются ВСЕМ моим пользовательским интерфейсом) с помощью простого статического вызова метода «rsWidget ()» следующим образом:
// Step 1: Define your widget however you like (this widget will be supplied as the "inWidget" arg to the "rsWidget" method in Step 2)... Widget _btnLogin = RaisedButton(color: Colors.blue, elevation: 9.0, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(McGyver.rsDouble(context, ScaleType.width, 2.5))), child: McGyver.rsText(context, "LOGIN", percFontSize: EzdFonts.button2_5, textColor: Colors.white, fWeight: FontWeight.bold), onPressed: () { _onTapBtnLogin(_tecUsrId.text, _tecUsrPass.text); }, ); // Step 2: Scale your widget by calling the static "rsWidget" method... McGyver.rsWidget(context, _btnLogin, 34.5, 10.0) // ...and Bob's your uncle!!
Замечательно то, что метод "rsWidget ()" возвращает виджет !! Таким образом, вы можете либо назначить масштабированный виджет другой переменной, например,
_rsBtnLogin
для использования повсюду, либо вы можете просто использовать полныйMcGyver.rsWidget()
вызов метода на месте внутри своегоbuild()
метода (именно так, как вам нужно, чтобы он располагался в дереве виджетов), и будет работать отлично как надо.Для более проницательных программистов: вы, наверное, заметили, что я использовал два дополнительных метода с пропорциональным масштабированием
McGyver.rsText()
иMcGyver.rsDouble()
(не определенные в приведенном выше коде) в моемRaisedButton()
- так что я в основном схожу с ума от этого масштабирования ... потому что я требую, чтобы мои приложения были абсолютно идеальный пиксель при любом масштабе и любой плотности экрана !! Я масштабирую свои целые числа, двойные числа, отступы, текст (все, что требует согласованности пользовательского интерфейса на разных устройствах). Я масштабирую свои тексты только по ширине, но указываю, какую ось использовать для всех других масштабов (как это было сделано сScaleType.width
перечислением, используемым дляMcGyver.rsDouble()
вызова в приведенном выше примере кода).Я знаю, что это безумие - и это большая работа, которую нужно сделать в основном потоке - но я надеюсь, что кто-то увидит мою попытку здесь и поможет мне найти лучшее (более легкое) решение для масштабирования моей плотности экрана 1: 1 кошмары.
источник
Вы можете использовать MediaQuery для родительского измерения или FractionallySizedBox в качестве контейнеров.
источник
Мой подход к проблеме аналогичен тому, как это сделал datayeah. У меня было много жестко запрограммированных значений ширины и высоты, и приложение отлично смотрелось на определенном устройстве. Итак, я получил высоту экрана устройства и просто создал коэффициент для масштабирования жестко запрограммированных значений.
double heightFactor = MediaQuery.of(context).size.height/708
где 708 - высота конкретного устройства.
источник
Я стараюсь сделать это как можно проще. действительно попробуйте. Я делаю отзывчивую утилиту с функцией getresponsivevalue, отвечающей за предоставление значения в соответствии с размером экрана, если вы не назначаете значение для среднего экрана, большого экрана, ландшафтного режима. По умолчанию она предоставляет значение, присвоенное короткому экрану. Добро пожаловать на любые вопросы. Я бы хотел улучшить
class SampleView extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Container( width: 200, height: 200, color: Responsive().getResponsiveValue( forLargeScreen: Colors.red, forMediumScreen: Colors.green, forShortScreen: Colors.yellow, forMobLandScapeMode: Colors.blue, context: context), ), );
}}
// utility class class Responsive { // function reponsible for providing value according to screensize getResponsiveValue( {dynamic forShortScreen, dynamic forMediumScreen, dynamic forLargeScreen, dynamic forMobLandScapeMode, BuildContext context}) { if (isLargeScreen(context)) { return forLargeScreen ?? forShortScreen; } else if (isMediumScreen(context)) { return forMediumScreen ?? forShortScreen; } else if (isSmallScreen(context) && isLandScapeMode(context)) { return forMobLandScapeMode ?? forShortScreen; } else { return forShortScreen; } } isLandScapeMode(BuildContext context) { if (MediaQuery.of(context).orientation == Orientation.landscape) { return true; } else { return false; } } static bool isLargeScreen(BuildContext context) { return getWidth(context) > 1200; } static bool isSmallScreen(BuildContext context) { return getWidth(context) < 800; } static bool isMediumScreen(BuildContext context) { return getWidth(context) > 800 && getWidth(context) < 1200; } static double getWidth(BuildContext context) { return MediaQuery.of(context).size.width; } }
источник
посмотрите эту страницу в вики по флаттеру:
Создание адаптивных приложений
источник
создать имя файла (app_config.dart) в имени папки (responseive_screen) в папке lib:
import 'package:flutter/material.dart'; class AppConfig { BuildContext _context; double _height; double _width; double _heightPadding; double _widthPadding; AppConfig(this._context) { MediaQueryData _queryData = MediaQuery.of(_context); _height = _queryData.size.height / 100.0; _width = _queryData.size.width / 100.0; _heightPadding = _height - ((_queryData.padding.top + _queryData.padding.bottom) / 100.0); _widthPadding = _width - (_queryData.padding.left + _queryData.padding.right) / 100.0; } double rH(double v) { return _height * v; } double rW(double v) { return _width * v; } double rHP(double v) { return _heightPadding * v; } double rWP(double v) { return _widthPadding * v; } }
тогда:
import 'responsive_screen/app_config.dart'; ... class RandomWordsState extends State<RandomWords> { AppConfig _ac; ... @override Widget build(BuildContext context) { _ac = AppConfig(context); ... return Scaffold( body: Container( height: _ac.rHP(50), width: _ac.rWP(50), color: Colors.red, child: Text('Test'), ), ); ... }
источник
Эту проблему можно решить с помощью MediaQuery.of (context)
Чтобы получить ширину экрана:
MediaQuery.of(context).size.width
Чтобы получить высоту экрана:
MediaQuery.of(context).size.height
Для получения дополнительной информации о часах MediaQuery Widget https://www.youtube.com/watch?v=A3WrA4zAaPw.
источник
padding: EdgeInsets.only( left: 4.0, right: ResponsiveWidget.isSmallScreen(context) ? 4: 74, //Check for screen type top: 10, bottom: 40),
Это нормально по рекомендации Google, но может быть не идеально.
источник
Используется ResponsiveBuilder или ScreenTypeLayout
import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:responsive_builder/responsive_builder.dart'; class Sample extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( elevation: 0, backgroundColor: Colors.black, ), body: ResponsiveBuilder( builder: (context, info) { var screenType = info.deviceScreenType; String _text; switch (screenType){ case DeviceScreenType.desktop: { _text = 'Desktop'; break; } case DeviceScreenType.tablet: { _text = 'Tablet'; break; } case DeviceScreenType.mobile: { _text = 'Mobile'; break; } case DeviceScreenType.watch: { _text = 'Watch'; break; } default: return null; } return Center(child: Text(_text, style: TextStyle(fontSize: 32, color: Colors.black),)); }, ), ); } } // screen type layout ScreenTypeLayout.builder( mobile: MobilePage(), tablet: TabletPage(), desktop: DesktopPage(), watch: Watchpage(), );
источник
Вы можете использовать responsive_helper пакет , чтобы сделать ваше приложение реагировать.
Это очень простой способ сделать ваше приложение адаптивным. Просто взгляните на страницу с примером, и тогда вы поймете, как ее использовать.
источник
Ширина:
MediaQuery.of(context).size.width
,Рост:
MediaQuery.of(context).size.height
,источник