我面临着根据各种屏幕尺寸使其响应的困难。如何使其响应?
@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
类:
MediaQueryData queryData;
queryData = MediaQuery.of(context);
MediaQuery:建立媒体查询解析给定数据的子树。
MediaQueryData:有关媒体(例如,窗口)的信息。
要获得设备像素比率:
queryData.devicePixelRatio
要获取设备屏幕的宽度和高度:
queryData.size.width
queryData.size.height
获取文本比例因子:
queryData.textScaleFactor
使用AspectRatio
类:
来自doc:
尝试将子项调整为特定宽高比的小部件。
小部件首先尝试布局约束所允许的最大宽度。通过将给定的宽高比应用于宽度来确定小部件的高度,表示为宽度与高度的比率。
例如,16:9宽度:高度纵横比的值为16.0 / 9.0。如果最大宽度为无穷大,则通过将纵横比应用于最大高度来确定初始宽度。
现在考虑第二个例子,这次宽高比为2.0,布局约束要求宽度介于0.0和100.0之间,高度介于0.0和100.0之间。我们将选择宽度为100.0(允许的最大值)和50.0的高度(以匹配宽高比)。
//example
new Center(
child: new AspectRatio(
aspectRatio: 100 / 100,
child: new Container(
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.orange,
)
),
),
),
我所做的是获取屏幕宽度和高度,并计算出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;
这对最近的一些项目非常有用。
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));
检查MediaQuery
课程
例如,要了解当前媒体的大小(例如,包含您的应用的窗口),您可以从
MediaQueryData.size
:MediaQueryData
返回的MediaQuery.of
中读取MediaQuery.of(context).size
属性。
所以你可以做到以下几点:
new Container(
height: MediaQuery.of(context).size.height/2,
.. )
从flutter wiki看看这个页面:
使用LayoutBuilder类:从其构建器属性中,您将获得BoxConstraints。检查约束的属性以确定要显示的内容。例如,如果您的maxWidth大于宽度断点,则返回一个Scaffold对象,其中一行在左侧有一个列表。如果它更窄,则返回带有包含该列表的抽屉的Scaffold对象。您还可以根据设备的高度,宽高比或其他属性调整显示。当约束发生变化时(例如,用户旋转手机,或将您的应用放入Nougat中的磁贴UI),构建功能将重新运行。
宽度:MediaQuery.of(context).size.width
,
身高:MediaQuery.of(context).size.height
,
在lib文件夹中的文件夹名称(responsive_screen)中创建文件名(app_config.dart):
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'),
),
);
...
}