Reputation: 1475
I am trying to build a rather simple Flutter form that consists of three rows of which the first two rows each hold three columns. I therefore made a Form that holds a Padding as a child, while this Padding has a Column as a child, which finally contains the three rows:
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextFormField(
validator: (value) {
if (value.isEmpty) {
return 'Please enter place of departure';
}
return null;
},
controller: fromController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'From'
),
),
RaisedButton(
onPressed: () => _selectDate(context),
child: Text('Select date'),
),
RaisedButton(
onPressed: () => _selectTime(context),
child: Text('Select time'),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextFormField(
validator: (value) {
if (value.isEmpty) {
return 'Please enter destination';
}
return null;
},
controller: toController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'To'
),
)
]
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RaisedButton(
onPressed: () {
// Validate returns true if the form is valid, or false
// otherwise.
if (_formKey.currentState.validate()) {
// If the form is valid, display a Snackbar.
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('You fly from '+fromController.text+' to '+toController.text)));
}
},
child: Text('Take off'),
),
]
),
],
),
),
);
}
Unfortunately this is not working this way and I can't figure out, how I need to structure the Form to build it successfully and leads to a render error. What I would like to build in the end would be something like this:
Upvotes: 1
Views: 4158
Reputation: 1141
While wrapping rows into column there should be size specified, You can wrap your rows && children's with Flexible or Expanded, this worked for your example:
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Flexible(
child: TextFormField(
validator: (value) {
if (value.isEmpty) {
return 'Please enter place of departure';
}
return null;
},
controller: fromController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'From'
),
),
),
Flexible(
child: RaisedButton(
onPressed: () => _selectDate(context),
child: Text('Select date'),
),
),
Flexible(
child: RaisedButton(
onPressed: () => _selectTime(context),
child: Text('Select time'),
),
),
],
),
),
Flexible(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Flexible(
child: TextFormField(
validator: (value) {
if (value.isEmpty) {
return 'Please enter destination';
}
return null;
},
controller: toController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'To'
),
),
)
]
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RaisedButton(
onPressed: () {
// Validate returns true if the form is valid, or false
// otherwise.
if (_formKey.currentState.validate()) {
// If the form is valid, display a Snackbar.
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('You fly from '+fromController.text+' to '+toController.text)));
}
},
child: Text('Take off'),
),
]
),
],
),
),
);
}
You might specify flex, work with expanded instead of flexibles & try some other mainAxisAlignment behaviours on your rows for the best effect, but in general it works pretty good
Upvotes: 3