相对于居中的小部件定位小部件
Position a widget relative to a centered widget
我正在制作登录页面。我希望 email/password 文本字段在页面中居中,按钮在最后一个字段下方 48dp(因此不考虑文本字段居中位置的计算)。
我不知道如何修改我的布局,使按钮不作为当前屏幕截图中显示的居中元素包含在内:
我的代码:
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(flex: 2, child: Container()),
Expanded(
flex: 8,
child: Form(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
RoundedTextField(
hintText: 'Email',
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
),
Container(
height: 12,
),
RoundedTextField.password(
hintText: 'Password',
textInputAction: TextInputAction.go,
),
Container(
height: 48,
),
PrimaryButton(
child: Text('Log In'),
onPressed: () => print(null),
),
],
),
),
),
Expanded(flex: 2, child: Container()),
]),
);
}
}
我来自 Android 开发世界,在那里我们可以做 constrainTopToBottomOf:@id/passwordField
,我不确定 flex 系统中是否真的有等价物。
最简单的解决方案是使用既不显示也不使用的按钮保持对称性:
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(flex: 2, child: Container()),
Expanded(
flex: 8,
child: Form(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Opacity(
opacity: 0.0,
child: RaisedButton(
child: Text(''),
onPressed: null,
),
),
Container(
height: 12,
),
TextField(
decoration: InputDecoration(hintText: 'Email'),
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
),
Container(
height: 12,
),
TextField(
decoration: InputDecoration(hintText: 'Password'),
textInputAction: TextInputAction.go,
),
Container(
height: 48,
),
RaisedButton(
child: Text('Log In'),
onPressed: () => print(null),
),
],
),
),
),
Expanded(flex: 2, child: Container()),
]),
);
}
}
有点骇人听闻,但您可以使用媒体查询设置高度:
double _height = MediaQuery.of(context).size.height * .5;
然后这样做:
body: Column(
children: <Widget>[
Container(
height: _height,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: 'email@email.com',
labelText: 'Email',
),
),
],
),
),
Container(
height: _height,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: 'email@email.com',
labelText: 'Email',
),
),
Padding(padding: EdgeInsets.only(top: 48.0)),
Text('some button'),
],
),
),
],
),
这个用例的常见解决方案是一个带有一些扩展的列:
Column(
children: [
Expanded(),
someContent,
Expanded(
child: someOffsetContent,
),
),
一个更直观的例子:(紫色是展开的)
Column(
children: <Widget>[
Expanded(child: Container(color: Colors.purple)),
Column(
children: <Widget>[
Container(
height: 42,
width: double.infinity,
color: Colors.red,
),
Container(
height: 42,
width: double.infinity,
color: Colors.yellow,
),
],
),
Expanded(
child: Container(
color: Colors.purple,
alignment: Alignment.topCenter,
padding: const EdgeInsets.only(top: 48),
child: Container(
color: Colors.red,
height: 42.0,
width: double.infinity,
),
),
)
],
)
我正在制作登录页面。我希望 email/password 文本字段在页面中居中,按钮在最后一个字段下方 48dp(因此不考虑文本字段居中位置的计算)。
我不知道如何修改我的布局,使按钮不作为当前屏幕截图中显示的居中元素包含在内:
我的代码:
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(flex: 2, child: Container()),
Expanded(
flex: 8,
child: Form(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
RoundedTextField(
hintText: 'Email',
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
),
Container(
height: 12,
),
RoundedTextField.password(
hintText: 'Password',
textInputAction: TextInputAction.go,
),
Container(
height: 48,
),
PrimaryButton(
child: Text('Log In'),
onPressed: () => print(null),
),
],
),
),
),
Expanded(flex: 2, child: Container()),
]),
);
}
}
我来自 Android 开发世界,在那里我们可以做 constrainTopToBottomOf:@id/passwordField
,我不确定 flex 系统中是否真的有等价物。
最简单的解决方案是使用既不显示也不使用的按钮保持对称性:
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(flex: 2, child: Container()),
Expanded(
flex: 8,
child: Form(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Opacity(
opacity: 0.0,
child: RaisedButton(
child: Text(''),
onPressed: null,
),
),
Container(
height: 12,
),
TextField(
decoration: InputDecoration(hintText: 'Email'),
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
),
Container(
height: 12,
),
TextField(
decoration: InputDecoration(hintText: 'Password'),
textInputAction: TextInputAction.go,
),
Container(
height: 48,
),
RaisedButton(
child: Text('Log In'),
onPressed: () => print(null),
),
],
),
),
),
Expanded(flex: 2, child: Container()),
]),
);
}
}
有点骇人听闻,但您可以使用媒体查询设置高度:
double _height = MediaQuery.of(context).size.height * .5;
然后这样做:
body: Column(
children: <Widget>[
Container(
height: _height,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: 'email@email.com',
labelText: 'Email',
),
),
],
),
),
Container(
height: _height,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: 'email@email.com',
labelText: 'Email',
),
),
Padding(padding: EdgeInsets.only(top: 48.0)),
Text('some button'),
],
),
),
],
),
这个用例的常见解决方案是一个带有一些扩展的列:
Column(
children: [
Expanded(),
someContent,
Expanded(
child: someOffsetContent,
),
),
一个更直观的例子:(紫色是展开的)
Column(
children: <Widget>[
Expanded(child: Container(color: Colors.purple)),
Column(
children: <Widget>[
Container(
height: 42,
width: double.infinity,
color: Colors.red,
),
Container(
height: 42,
width: double.infinity,
color: Colors.yellow,
),
],
),
Expanded(
child: Container(
color: Colors.purple,
alignment: Alignment.topCenter,
padding: const EdgeInsets.only(top: 48),
child: Container(
color: Colors.red,
height: 42.0,
width: double.infinity,
),
),
)
],
)