flutter - 如何使用 MediaQuery 管理不同设备的屏幕布局?
问题描述
我已经将 MediaQuery 用于响应式设计,但我没有得到想要的结果。请指导我并帮助我。我在不同的移动设备上得到不同的 UI。请告诉我我哪里错了,或者指导我使用正确的代码来使用 MediaQuery 进行响应式设计。我不想使用 SingleChildScrollView,因为它是登录屏幕。所以,我希望它能够响应所有设备,包括不同尺寸的标签和手机。下面是我的代码:
import 'dart:ui';
import 'package:conqer_music/App/Controller/UserController.dart';
import 'package:mvc_pattern/mvc_pattern.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:conqer_music/App/Repository/UserRepository.dart' as userRepo;
class LoginPage extends StatefulWidget {
static const String routeName = '/loginPage';
@override
_LoginState createState() => _LoginState();
}
final _formKey = GlobalKey<FormState>();
class _LoginState extends State<LoginPage> {
late UserController _con;
// _LoginState() : super(UserController()) {
// _con = controller;
@override
void initState() {
super.initState();
if (userRepo.currentUser.value.apiToken != null) {
Navigator.of(context).pushReplacementNamed('/Pages', arguments: 2);
}
}
bool _rememberMe = false;
Widget logo() {
final screenHeight = MediaQuery.of(context).size.height;
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: screenHeight * 0.08)),
CircleAvatar(
child: Image.asset('lib/App/Assets/Images/Logo.png'),
backgroundColor: Colors.grey,
radius: 80.0,
),
SizedBox(
height: 10.0,
),
Text(
'LOGIN',
style: TextStyle(
fontSize: 28.0, fontWeight: FontWeight.bold, color: Colors.white),
textAlign: TextAlign.center,
),
],
);
}
Widget backgroundImage() {
return Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
constraints: BoxConstraints.expand(),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('lib/App/Assets/Images/BackGround.png'),
fit: BoxFit.cover)),
)
],
),
);
}
Widget userPass() {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return Expanded(
child: Container(
height: screenHeight * 0.2,
width: screenWidth * 0.8,
child: Column(
children: <Widget>[
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Username';
}
return null;
},
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
hintText: 'Username',
hintStyle: TextStyle(
color: Color(0xFFbaa15e),
),
suffixIcon: Icon(Icons.verified_user_sharp),
border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(20.0),
),
),
style: TextStyle(
color: Colors.black,
fontSize: 12,
textBaseline: TextBaseline.alphabetic),
),
SizedBox(height: 20),
TextFormField(
validator: (String? pass) {
if (pass!.length == 0) {
return 'Please Enter Password';
}
},
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
hintText: 'Password',
hintStyle: TextStyle(color: Color(0xFFbaa15e)),
suffixIcon: Icon(Icons.security_rounded),
border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(20.0),
),
),
style: TextStyle(color: Colors.black, fontSize: 12),
),
],
),
),
);
}
Widget rememberMe() {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return Container(
height: screenHeight * 0.05,
// width: screenWidth * 0.4,
padding: EdgeInsets.only(left: 40),
child: Row(
children: <Widget>[
Checkbox(
value: _rememberMe,
checkColor: Colors.green,
activeColor: Colors.white,
onChanged: (value) {
setState(() {
_rememberMe = value!;
});
},
),
Text(
'Remember Me',
style: TextStyle(color: Colors.white, fontSize: 14),
),
],
),
);
}
Widget loginButton() {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return Container(
// height: screenHeight * 0.1,
width: screenWidth * 0.8,
child: RaisedButton(
elevation: 4.0,
onPressed: () {
Navigator.of(context).pushReplacementNamed('/MainPage');
if (_formKey.currentState!.validate()) {
Navigator.of(context).pushReplacementNamed('/MainPage');
_con.login();
}
},
// if (_formKey.currentState!.validate()) {
// Navigator.of(context).pushReplacementNamed('/MainPage'),
// },
padding: EdgeInsets.all(15.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: Color(0xFFbaa15e),
child: Text(
'LOGIN',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 14.0,
fontWeight: FontWeight.bold,
fontFamily: 'OpenSans',
),
),
),
);
}
Widget forgotPasswordhelp() {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return Container(
padding: EdgeInsets.fromLTRB(
screenWidth * 0.14, 0, screenWidth * 0.14, screenHeight * 0.09),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Forgot Password?',
style: TextStyle(
color: Color(0xFFbaa15e),
),
),
Text(
'Help?',
style: TextStyle(
color: Color(0xFFbaa15e),
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
body: Container(
height: screenHeight,
width: screenWidth,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('lib/App/Assets/Images/BackGround.png'),
fit: BoxFit.cover)),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
logo(),
SizedBox(
height: 10,
),
userPass(),
rememberMe(),
SizedBox(
height: 10,
),
loginButton(),
SizedBox(
height: 5,
),
forgotPasswordhelp()
],
),
),
);
}
}
解决方案
Flutter 并不能让你轻松地为移动设备构建响应式应用程序。一种解决方法是检测设备方向并根据您的需要更改容器的高度和宽度。一种方法是使用 Container 小部件的“mediaquery”属性。
width: MediaQuery.of(context).orientation == Orientation.landscape ? 25 : 14
如果设备处于横向模式,这会将容器的宽度更改为 25,如果设备处于纵向模式,则将宽度更改为 14。你也可以对 height 属性做同样的事情。
推荐阅读
- spring-kafka - 如何在 @KafkaListener 中使用 ContainerStoppingErrorHandler 来终止应用程序以防 Kafka 服务器出现 DisconnectException
- jquery - 如何在数据表中的鼠标悬停时显示图像预览
- databricks - folium 地图未显示 datbricks python
- oracle - 需要通过oracle forms 10g打开一个PDF文档
- reactjs - 如何在 REST API 中实现代码授权流程?
- proguard - 语句顺序是否重要/Proguard 中是否有优先级?
- javascript - 如何使用javascript从某个url调用具有某个类的div
- snmp - 是否有一个可以从经理那里读取 snmptraps 的电报插件?
- javascript - 如何在点击时设置输入组内变量的状态?
- javascript - 尝试嵌入此视频时找不到视频播放器的名称