Estou enfrentando dificuldades para torná-lo responsivo de acordo com vários tamanhos de tela. Como torná-lo responsivo?
@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
seja suficiente. Você pode querer dar uma olhada.Respostas:
Usando a
MediaQuery
classe:Para obter o Device Pixel Ratio:
Para obter a largura e a altura da tela do dispositivo:
Para obter o fator de escala do texto:
Usando a
AspectRatio
classe:Do doc:
//example new Center( child: new AspectRatio( aspectRatio: 100 / 100, child: new Container( decoration: new BoxDecoration( shape: BoxShape.rectangle, color: Colors.orange, ) ), ), ),
Você também pode usar :
fonte
queryData
.Esta classe ajudará e então inicializará a classe com o método 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; } }
então em sua dimensão de widgets faça isso
Widget build(BuildContext context) { SizeConfig().init(context); return Container( height: SizeConfig.safeBlockVertical * 10, //10 for example width: SizeConfig.safeBlockHorizontal * 10, //10 for example );}
Todos os créditos para este autor de postagem: https://medium.com/flutter-community/flutter-effectively-scale-ui-according-to-different-screen-sizes-2cb7c115ea0a
fonte
O que eu faço é pegar a largura e a altura da tela e calcular uma grade de 100 * 100 para posicionar e dimensionar as coisas e salvá-las como variáveis estáticas que podem ser reutilizadas. Funciona muito bem na maioria dos casos. Como isso:
AppConfig.width = MediaQuery.of(context).size.width; AppConfig.height = MediaQuery.of(context).size.height; AppConfig.blockSize = AppConfig.width / 100; AppConfig.blockSizeVertical = AppConfig.height / 100;
Então eu dimensiono tudo de acordo com estes valores, assim:
double elementWidth = AppConfig.blockSize * 10.0; // 10% of the screen width
ou
double fontSize = AppConfig.blockSize * 1.2;
Às vezes, a área segura (entalhe etc.) mata um layout, então você também pode considerar isso:
AppConfig.safeAreaHorizontal = MediaQuery.of(context).padding.left + MediaQuery.of(context).padding.right; double screenWidthWithoutSafeArea = AppConfig.width - AppConfig.safeAreaHorizontal;
Isso funcionou muito bem em alguns projetos recentes.
fonte
Verificar
MediaQuery
aulaPortanto, você pode fazer o seguinte:
new Container( height: MediaQuery.of(context).size.height/2, .. )
fonte
A maneira mais fácil de tornar a interface do usuário responsiva para tamanhos de tela diferentes é o plug-in Sizer .
Faça UI responsiva em qualquer dispositivo de tamanho de tela e tablet. Verifique este plugin ⬇️
https://pub.dev/packages/sizer
.h - for widget height .w - for widget width .sp - for font size
Use
.h
,.w
,.sp
após o valor como este ⬇️Exemplo:
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)), );
Eu construí muitos aplicativos responsivos com este plugin.
fonte
Você pode obter uma porcentagem da largura ou altura como entrada para o tamanho da escala.
fontSize: MediaQuery.of(_ctxt).size.height * 0.065
Onde o multiplicador no final tem um valor que faz o texto parecer bom para o emulador ativo.
Abaixo está como eu configurei para que todas as dimensões em escala sejam centralizadas em um só lugar. Dessa forma, você pode ajustá-los de forma fácil e rápida e executar novamente com Hot Reload sem ter que procurar as
Media.of()
chamadas em todo o código.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), );
Graças às respostas neste post
fonte
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));
fonte
Depois de muita pesquisa e testes, desenvolvi uma solução para um aplicativo que estou convertendo de Android / iOS para Flutter.
Com o Android e o iOS, usei um 'fator de escala' aplicado aos tamanhos de fonte básicos, renderizando os tamanhos de texto relativos ao tamanho da tela.
Este artigo foi muito útil: https://medium.com/flutter-community/flutter-effectively-scale-ui-according-to-different-screen-sizes-2cb7c115ea0a
Criei um StatelessWidget para obter os tamanhos das fontes dos estilos tipográficos do Material Design. Obter dimensões do dispositivo usando MediaQuery, calcular um fator de escala e, em seguida, redefinir os tamanhos de texto do Material Design. O widget pode ser usado para definir um tema personalizado do Material Design.
Emuladores usados:
Com tamanhos de fonte padrão
Com tamanhos de fonte redimensionados
set_app_theme.dart (widget 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 (aplicativo de demonstração)
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, ), ), ], ), ), ), ), ), ); } }
fonte
Tenho criticado as soluções de outras pessoas (@datayeah & Vithani Ravi) um pouco difícil aqui, então pensei em compartilhar minhas próprias tentativas de resolver esse problema de dimensionamento de densidade de tela variável ou calar a boca. Portanto, abordo este problema a partir de uma base sólida / fixa: baseio todo o meu dimensionamento em uma proporção fixa (imutável) de 2: 1 (altura: largura). Eu tenho uma classe auxiliar "McGyver" que faz todo o trabalho pesado (e ajuste de código útil) em meu aplicativo. Esta classe "McGyver" contém apenas métodos estáticos e membros da classe constante estática.
MÉTODO DE ESCALA DE RAZÃO: Eu dimensiono a largura e a altura independentemente com base na proporção de aspecto 2: 1. Eu pego os valores de entrada de largura e altura e divido cada um pelas constantes de largura e altura e, finalmente, calculo um fator de ajuste pelo qual escalono os respectivos valores de entrada de largura e altura. O código real é o seguinte:
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, ); } }
... ... ...
Em seguida, você dimensionaria individualmente seus widgets (que para minha doença perfeccionista é TODA a minha IU) com uma chamada estática simples para o método "rsWidget ()" da seguinte maneira:
// 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!!
O legal é que o método "rsWidget ()" retorna um widget !! Portanto, você pode atribuir o widget escalado a outra variável
_rsBtnLogin
para usar em qualquer lugar - ou pode simplesmente usar aMcGyver.rsWidget()
chamada de método completa no local dentro de seubuild()
método (exatamente como você precisa que seja posicionado na árvore do widget) e funcionará perfeitamente como deveria.Para os codificadores mais astutos: você deve ter notado que usei dois métodos escalonados de proporção adicionais
McGyver.rsText()
eMcGyver.rsDouble()
(não definidos no código acima) no meuRaisedButton()
- então, basicamente, enlouqueço com essas coisas de escalonamento ... porque exijo que meus aplicativos sejam absolutamente pixel perfeito em qualquer escala ou densidade de tela !! Eu dimensiono a proporção de meus ints, duplos, preenchimento, texto (tudo que requer consistência de IU entre dispositivos). Eu dimensiono meus textos apenas com base na largura, mas especifico qual eixo usar para todas as outras escalas (como foi feito com oScaleType.width
enum usado para aMcGyver.rsDouble()
chamada no exemplo de código acima).Eu sei que isso é uma loucura - e é muito trabalho a fazer no thread principal - mas eu espero que alguém veja minha tentativa aqui e me ajude a encontrar uma solução melhor (mais leve) para minha densidade de tela de escala 1: 1 pesadelos.
fonte
Você pode usar MediaQuery para a dimensão do pai ou FractionallySizedBox como contêineres.
fonte
Minha abordagem do problema é semelhante à maneira como datayeah o fez. Eu tinha muitos valores codificados de largura e altura e o aplicativo parecia bom em um dispositivo específico. Peguei a altura da tela do dispositivo e acabei de criar um fator para dimensionar os valores codificados.
double heightFactor = MediaQuery.of(context).size.height/708
onde 708 é a altura do dispositivo específico.
fonte
Tento tornar isso o mais simples possível. experimente. Eu faço um utilitário responsivo tendo a função getresponsivevalue responsável por fornecer valor de acordo com o tamanho da tela se você não atribuir valor para uma tela média, tela grande, modo paisagem Por padrão, fornece um valor atribuído para tela curta. uma recepção calorosa para qualquer dúvida. Eu adoraria melhorar
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; } }
fonte
confira esta página do flutter wiki:
Criação de aplicativos responsivos
fonte
crie o nome do arquivo (app_config.dart) no nome da pasta (responsive_screen) na pasta 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; } }
então:
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'), ), ); ... }
fonte
Este problema pode ser resolvido usando MediaQuery.of (contexto)
Para obter a largura da tela:
MediaQuery.of(context).size.width
Para obter a altura da tela:
MediaQuery.of(context).size.height
Para obter mais informações sobre o MediaQuery Widget watch, https://www.youtube.com/watch?v=A3WrA4zAaPw
fonte
padding: EdgeInsets.only( left: 4.0, right: ResponsiveWidget.isSmallScreen(context) ? 4: 74, //Check for screen type top: 10, bottom: 40),
Isso é bom por recomendação do Google, mas pode não ser perfeito.
fonte
ResponsiveBuilder usado ou 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(), );
fonte
Você pode usar o pacote responsive_helper para tornar seu aplicativo responsivo.
É um método muito fácil de tornar seu aplicativo responsivo. Basta dar uma olhada na página de exemplo e então você descobrirá como usá-la.
fonte
Largura:
MediaQuery.of(context).size.width
,Altura:
MediaQuery.of(context).size.height
,fonte