Mam trudności z dostosowaniem go do różnych rozmiarów ekranu. Jak sprawić, by był responsywny?
@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: () {})
]),
),
),
),
],
),
);
}
}
queryData
.Ta klasa pomoże, a następnie zainicjuje klasę metodą 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; } }
zrób to w swoim wymiarze widgetów
Widget build(BuildContext context) { SizeConfig().init(context); return Container( height: SizeConfig.safeBlockVertical * 10, //10 for example width: SizeConfig.safeBlockHorizontal * 10, //10 for example );}
Wszystkie podziękowania dla autora tego postu: https://medium.com/flutter-community/flutter-effectively-scale-ui-according-to-different-screen-sizes-2cb7c115ea0a
źródło
To, co robię, to wziąć szerokość i wysokość ekranu i obliczyć z niego siatkę 100 * 100, aby ustawić i skalować rzeczy, a następnie zapisać ją jako zmienne statyczne, które można ponownie wykorzystać. W większości przypadków działa całkiem dobrze. Lubię to:
AppConfig.width = MediaQuery.of(context).size.width; AppConfig.height = MediaQuery.of(context).size.height; AppConfig.blockSize = AppConfig.width / 100; AppConfig.blockSizeVertical = AppConfig.height / 100;
Następnie skaluję wszystko zgodnie z tymi wartościami, na przykład:
double elementWidth = AppConfig.blockSize * 10.0; // 10% of the screen width
lub
double fontSize = AppConfig.blockSize * 1.2;
Czasami bezpieczny obszar (wycięcie itp.) Zabija układ, więc możesz również rozważyć to:
AppConfig.safeAreaHorizontal = MediaQuery.of(context).padding.left + MediaQuery.of(context).padding.right; double screenWidthWithoutSafeArea = AppConfig.width - AppConfig.safeAreaHorizontal;
To działało świetnie w niektórych ostatnich projektach.
źródło
Sprawdź
MediaQuery
klasęMożesz więc wykonać następujące czynności:
new Container( height: MediaQuery.of(context).size.height/2, .. )
źródło
Możesz wziąć procent szerokości lub wysokości jako dane wejściowe dla rozmiaru skali.
fontSize: MediaQuery.of(_ctxt).size.height * 0.065
Gdzie mnożnik na końcu ma wartość, która sprawia, że tekst wygląda dobrze dla aktywnego emulatora.
Poniżej przedstawiam, jak to skonfigurowałem, aby wszystkie skalowane wymiary były scentralizowane w jednym miejscu. W ten sposób można je łatwo i szybko dostosować ponownie za pomocą funkcji Hot Reload bez konieczności wyszukiwania
Media.of()
wywołań w całym kodzie.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), );
Dzięki odpowiedziom w tym poście
źródło
Trochę ciężko pukałem tutaj rozwiązania innych ludzi (@datayeah i Vithani Ravi), więc pomyślałem, że podzielę się własnymi próbami rozwiązania tego problemu ze zmienną gęstością ekranu lub zamknę się. Więc podchodzę do tego problemu od solidnego / stałego fundamentu: opieram całe moje skalowanie na stałym (niezmiennym) stosunku 2: 1 (wysokość: szerokość). Mam klasę pomocniczą „McGyver”, która wykonuje wszystkie czynności związane z podnoszeniem ciężarów (i użyteczną finezją kodu) w mojej aplikacji. Ta klasa „McGyver” zawiera tylko statyczne metody i statyczne stałe elementy składowe.
METODA SKALOWANIA RATIO: Skaluję zarówno szerokość, jak i wysokość niezależnie w oparciu o współczynnik proporcji 2: 1. Biorę wartości wejściowe szerokości i wysokości i dzielę je przez stałe szerokości i wysokości, a na koniec obliczam współczynnik korekty, za pomocą którego skaluję odpowiednie wartości wejściowe szerokości i wysokości. Rzeczywisty kod wygląda następująco:
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, ); } }
... ... ...
Następnie indywidualnie skalowałbyś swoje widżety (które dla mojej perfekcjonistycznej choroby to CAŁY mój interfejs użytkownika) za pomocą prostego statycznego wywołania metody „rsWidget ()” w następujący sposób:
// 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!!
Fajne jest to, że metoda "rsWidget ()" zwraca widżet !! Możesz więc przypisać skalowany widżet do innej zmiennej, na przykład
_rsBtnLogin
do użytku w dowolnym miejscu - lub możesz po prostu użyć pełnegoMcGyver.rsWidget()
wywołania metody wewnątrz swojejbuild()
metody (dokładnie tak, jak chcesz, aby był umieszczony w drzewie widżetów) i będzie działał idealnie tak, jak powinien.Dla tych bardziej wnikliwych programistów: zauważyliście, że użyłem dwóch dodatkowych metod skalowanych współczynnikiem
McGyver.rsText()
iMcGyver.rsDouble()
(nie zdefiniowanych w powyższym kodzie) w moimRaisedButton()
- więc po prostu szaleję z tym skalowaniem ... ponieważ wymagam, aby moje aplikacje były absolutnie doskonały piksel w dowolnej skali i gęstości ekranu !! Skaluję proporcjonalnie moje ints, double, padding, text (wszystko, co wymaga spójności interfejsu użytkownika na różnych urządzeniach). Skaluję moje teksty tylko na podstawie szerokości, ale określam, której osi użyć do wszystkich innych skalowań (tak jak zostało to zrobione zScaleType.width
wyliczeniem używanym doMcGyver.rsDouble()
wywołania w powyższym przykładzie kodu).Wiem, że to szalone - i mam dużo pracy do wykonania w głównym wątku - ale mam nadzieję, że ktoś zobaczy tutaj moją próbę i pomoże mi znaleźć lepsze (lżejsze) rozwiązanie dla mojego skalowania 1: 1 z gęstością ekranu koszmary.
źródło
Po wielu badaniach i testach opracowałem rozwiązanie dla aplikacji, którą obecnie konwertuję z systemu Android / iOS na Flutter.
W systemie Android i iOS użyłem „współczynnika skalowania” zastosowanego do podstawowych rozmiarów czcionek, renderując rozmiary tekstu, które były zależne od rozmiaru ekranu.
Ten artykuł był bardzo pomocny: https://medium.com/flutter-community/flutter-effectively-scale-ui-according-to-different-screen-sizes-2cb7c115ea0a
Utworzyłem StatelessWidget, aby uzyskać rozmiary czcionek stylów typograficznych Material Design. Pobieranie wymiarów urządzenia za pomocą MediaQuery, obliczanie współczynnika skalowania, a następnie resetowanie rozmiarów tekstu Material Design. Widżetu można użyć do zdefiniowania niestandardowego motywu Material Design.
Zastosowane emulatory:
Ze standardowymi rozmiarami czcionek
Ze skalowanymi rozmiarami czcionek
set_app_theme.dart (widżet 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 (aplikacja demonstracyjna)
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, ), ), ], ), ), ), ), ), ); } }
źródło
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));
źródło
Możesz użyć MediaQuery dla wymiaru nadrzędnego lub FractionallySizedBox jako kontenerów.
źródło
Moje podejście do problemu jest podobne do sposobu, w jaki zrobił to datayeah. Miałem wiele wartości szerokości i wysokości zakodowanych na stałe, a aplikacja wyglądała dobrze na określonym urządzeniu. Otrzymałem więc wysokość ekranu urządzenia i właśnie utworzyłem współczynnik skalowania zakodowanych wartości.
double heightFactor = MediaQuery.of(context).size.height/708
gdzie 708 to wysokość konkretnego urządzenia.
źródło
Staram się, aby było to tak proste, jak to tylko możliwe. spróbuj. Tworzę responsywne narzędzie z funkcją getresponsivevalue odpowiedzialną za dostarczanie wartości zgodnie z rozmiarem ekranu, jeśli nie przypisujesz wartości do średniego ekranu, dużego ekranu, trybu poziomego. Domyślnie zapewnia wartość przypisaną do krótkiego ekranu. serdecznie witamy w przypadku jakichkolwiek pytań. Bardzo chciałbym się poprawić
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; } }
źródło
Najłatwiejszym sposobem na stworzenie responsywnego interfejsu użytkownika dla różnych rozmiarów ekranu jest wtyczka Sizer .
Zrób responsywny interfejs użytkownika na urządzeniu o dowolnym rozmiarze ekranu, a także tablecie. Sprawdź tę wtyczkę ⬇️
https://pub.dev/packages/sizer
.h - for widget height .w - for widget width .sp - for font size
Posługiwać się
.h
,.w
,.sp
po wartości jak ta ⬇️Przykład:
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)), );
Zbudowałem wiele responsywnych aplikacji z tą wtyczką.
źródło
sprawdź tę stronę na flutter wiki:
Tworzenie responsywnych aplikacji
źródło
utwórz nazwę pliku (app_config.dart) w nazwie folderu (responsive_screen) w folderze 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; } }
następnie:
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'), ), ); ... }
źródło
Ten problem można rozwiązać za pomocą MediaQuery.of (kontekst)
Aby uzyskać szerokość ekranu:
MediaQuery.of(context).size.width
Aby uzyskać wysokość ekranu:
MediaQuery.of(context).size.height
Aby uzyskać więcej informacji na temat zegarka MediaQuery Widget, https://www.youtube.com/watch?v=A3WrA4zAaPw
źródło
padding: EdgeInsets.only( left: 4.0, right: ResponsiveWidget.isSmallScreen(context) ? 4: 74, //Check for screen type top: 10, bottom: 40),
Jest to w porządku według zaleceń Google, ale może nie być idealne.
źródło
Użyto ResponsiveBuilder lub 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(), );
źródło
Możesz użyć pakietu responsive_helper , aby Twoja aplikacja była responsywna.
To bardzo łatwa metoda, aby Twoja aplikacja była responsywna. Wystarczy spojrzeć na przykładową stronę, a wtedy dowiesz się, jak z niej korzystać.
źródło
Szerokość:
MediaQuery.of(context).size.width
,Wzrost:
MediaQuery.of(context).size.height
,źródło