我正在构建一个由各种Widgets组成的表单,我想将它们全部对齐。
在下面的示例中,我使用的是TextFormField,ListTile等。
问题与TextFormField>的对齐有关。装饰> icon和ListTile>领先。
正如您所见,ListTile>前导绝对不与TextFormField>对齐;装饰>图标。
在文档中,我找不到有关如何调整ListTile的任何解释>领先"保证金离开"
子问题:如何设置ListTile标题和副标题的样式,使其看起来像TextFormField?
任何帮助都非常受欢迎。
源代码提取:
_buildBody() {
return new SafeArea(
top: false,
bottom: false,
child: new Form(
key: _formKey,
autovalidate: false,
child: new SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
/* -- Profile Picture -- */
const SizedBox(height: 24.0),
_buildProfilePicture(),
/* -- Alias -- */
new TextFormField(
decoration: const InputDecoration(
border: const UnderlineInputBorder(),
filled: true,
icon: const Icon(Icons.person),
hintText: 'Enter an alias',
labelText: 'Alias *',
),
onSaved: (String value) {
profile.alias = value;
},
validator: _validateAlias,
),
const SizedBox(height: 24.0),
/* -- Gender -- */
_buildGender(context),
const SizedBox(height: 24.0),
/* -- Self description -- */
new TextFormField(
decoration: const InputDecoration(
border: const OutlineInputBorder(),
hintText: 'Tell us about yourself',
labelText: 'Describe yourself',
),
maxLines: 5,
),
const SizedBox(height: 24.0),
/* -- Save Button -- */
new Center(
child: new RaisedButton(
child: const Text('Save'),
onPressed: _handleSave,
),
),
const SizedBox(height: 24.0),
],
),
),
),
);
}
_buildGender(BuildContext context) {
return new GestureDetector(
child: new ListTile(
leading: new Container(width: 24.0, height: 24.0, color: Colors.red),//const Icon(Icons.casino),
title: const Text('Gender'),
subtitle: new Text(profile.gender),
trailing: const Icon(Icons.arrow_drop_down),
dense: true,
),
onTap: () async {
await showModalBottomSheet<void>(
context: context,
builder: (BuildContext context){
return _buildGenderBottomPicker();
},
);
}
);
}
答案 0 :(得分:2)
由于我无法找到适应ListTile的任何直接解决方案,并且无法通过负余量来更正ListTile设置的默认值(请参阅其源代码),我决定构建自己的一个(简化版):
这是我带来的解决方案:
_buildGender(BuildContext context) {
List<Widget> children = <Widget>[];
/* -- leading -- */
children.add(new Container(
width: 40.0,
alignment: AlignmentDirectional.centerStart,
child: const Icon(Icons.album, color: Colors.grey),
));
/* -- title & subtitle -- */
children.add(new Expanded(
child: new Container(
height: 48.0,
padding: const EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0),
decoration: new BoxDecoration(
color: Color.fromRGBO(0, 0, 0, 0.05),
border: new Border(bottom: new BorderSide(color: Colors.black)),
),
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text('Gender',
style: new TextStyle(color: Colors.blue, fontSize: 12.0)),
const SizedBox(height: 5.0),
new Text(profile.gender),
],
),
),
));
/* -- trailing -- **/
children.add(new Container(
width: 40.0,
height: 48.0,
alignment: AlignmentDirectional.centerEnd,
decoration: new BoxDecoration(
color: Color.fromRGBO(0, 0, 0, 0.05),
border: new Border(bottom: new BorderSide(color: Colors.black)),
),
child: const Icon(Icons.arrow_drop_down),
));
return new InkWell(
child: new Semantics(
child: new ConstrainedBox(
constraints: new BoxConstraints(minHeight: 60.0),
child: new UnconstrainedBox(
constrainedAxis: Axis.horizontal,
child: new SafeArea(
top: false,
bottom: false,
child: new Row(children: children),
),
),
),
),
onTap: () async {
await showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return _buildGenderBottomPicker();
},
);
});
}
和我获得的布局:
当然还有一些工作要做,以改进代码,使用主题,最后使它成为一个小部件,但这是一个开始。
我只是想和你分享这段代码。
答案 1 :(得分:2)
只需将图标包装在容器中,高度为:double.infinity
ListTile(
leading: Container(
child:
Icon(Icons.account_circle),
height: double.infinity,)
答案 2 :(得分:1)