【发布时间】:2020-12-23 15:54:47
【问题描述】:
我正在开发一个 Flutter 应用,下面是我的 UI 代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height),
child: Container(child: _LoginUI(),),)
),
);
}
}
class _LoginUI extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _LoginState();
}
}
class _LoginState extends State<_LoginUI> {
final _formKey = GlobalKey<FormState>();
//FIXME When validate error occures, the fields get super small
TextEditingController _phoneNumber = TextEditingController();
TextEditingController _passwordController = TextEditingController();
@override
Widget build(BuildContext context) {
return Container(
height: double.infinity,
width: double.infinity,
child:
Stack(
fit: StackFit.loose,
children: <Widget>[
SafeArea(
child: Container(
margin: EdgeInsets.only(top: 25),
child: Image.asset("assets/images/login_image.png"),
),
),
Positioned(
top: 275,
child: Container(
height: 600,
width: MediaQuery.of(context).size.width,
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(40.0),
topRight: const Radius.circular(40.0))),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: Container(
margin:
EdgeInsets.only(top: 20, left: 10, right: 10),
child: Image.asset(
"assets/images/logo.png",
width: 200,
height: 50),
),
)
],
),
Form(
key: _formKey,
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(
top: 40,
),
child: SizedBox(
width: MediaQuery.of(context).size.width * .90,
height: 36,
child: TextFormField(
controller: _phoneNumber,
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.only(
top: 2, bottom: 2, left: 8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
hintText: "Email",
),
),
)),
Container(
margin: EdgeInsets.only(
top: 15,
),
child: SizedBox(
height: 36,
width: MediaQuery.of(context).size.width * .90,
child: TextFormField(
controller: _passwordController,
keyboardType: TextInputType.visiblePassword,
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.only(
top: 2, bottom: 2, left: 8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
hintText: "Password",
),
),
),
),
Align(
alignment: Alignment.bottomRight,
child: Container(
margin: EdgeInsets.only(
top: 1, left: 10, right: 10),
child: FlatButton(
onPressed: () {
Navigator.pushNamed(context, "/password-reset");
},
child: Text("Forgot Password?",
style: TextStyle(
fontFamily: 'Roboto-Medium',
fontSize: 14.0,
letterSpacing: 1.25,
color:
Color.fromRGBO(75, 56, 137, 80))),
)),
),
Container(
margin:
EdgeInsets.only(top: 1, left: 10, right: 10),
child: SizedBox(
width: MediaQuery.of(context).size.width * .90,
child: RaisedButton(
color: Color.fromRGBO(75, 56, 137, 80),
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius:
new BorderRadius.circular(18.0),
side: BorderSide(
color:
Color.fromRGBO(75, 56, 137, 80))),
child: Text(
"LOGIN",
style: Theme.of(context).textTheme.button,
),
onPressed: () {
String email = _phoneNumber.text;
String password = _passwordController.text;
if (_formKey.currentState.validate()) {
loginProcess(email, password);
}
},
),
))
],
),
),
Container(
margin: EdgeInsets.only(top: 1, left: 10, right: 10),
child: FlatButton(
onPressed: () {
Navigator.pushNamed(context, "/register");
},
child: RichText(
text: TextSpan(children: <TextSpan>[
TextSpan(
text: "Not a member yet? ",
style: TextStyle(fontFamily: 'Roboto-Regular', fontSize: 14.0, letterSpacing: 0.25, color:Color.fromRGBO(75, 56, 137, 80 )),
),
TextSpan(
text: "Create an Account",
style: TextStyle(decoration: TextDecoration.underline, fontFamily: 'Roboto-Regular', fontSize: 14.0, letterSpacing: 0.25, color:Color.fromRGBO(75, 56, 137, 80 ),
),)
]),
),
)),
],
),
),
),
],
)
//child: Image.asset("assets/images/login_image.png"),
);
}
bELOW 图片显示了我在大多数手机中获得的 UI 是正确的,而我在某些手机中获得的 UI 是不准确的。
如您所见,在不准确的版本中,底部的按钮缺失。这特别发生在Sony Xperia 系列中,它的屏幕尺寸为 4.6 英寸,分辨率为 720x1280。
解决此问题的最简单方法是将positioned 中的值更改为 250,这会使图像下方的整个块更加向上。但这在某些手机中很难看,因为它覆盖了顶部图像。我有另一个与此问题相同的屏幕,它有更多字段。因此,将 positioned 值设置为其他值这样的解决方案将不起作用。
确保整个屏幕在所有手机中可见的最佳解决方案是什么?
【问题讨论】:
标签: android ios flutter flutter-layout