Reputation: 5419
I have a page of my app that consists solely of a Card
that holds a Column
at the end of which is a MaterialList
. Even if my list only has one or two items, the Card extends its vertical space to the bottom of the screen rather than stopping at the end of the list items. The Column documentation suggests this is normal Column behavior ("Layout each child a null or zero flex factor (e.g., those that are not Expanded) with unbounded vertical constraints"). I thought wrapping the list in a Flexible
might achieve my desired effect but when I tried I got the following error:
RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I/flutter (11469): When a column is in a parent that does not provide a finite height constraint, for example if it is
I/flutter (11469): in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
I/flutter (11469): flex on a child (e.g. using a Flexible) indicates that the child is to expand to fill the remaining
I/flutter (11469): space in the vertical direction.
I/flutter (11469): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
I/flutter (11469): cannot simultaneously expand to fit its parent.
I'm clearly misunderstanding something about how this layout is supposed to work.
Here is sample code of what I have now as the body of the Scaffold
for this page:
new Container(
// Outer container so we can set margins and padding for the cards
// that will hold the rest of the view.
alignment: FractionalOffset.topCenter,
margin: new EdgeInsets.only(top: style.wideMargin),
padding: new EdgeInsets.symmetric(horizontal: style.defaultMargin),
child: new Card(
child: new Column(
children: [
new CustomHeader(), // <-- a Row with some buttons in it
new Divider(),
new MaterialList(
type: MaterialListType.twoLine,
children: listItems, // <-- a list of custom Rows
),
],
),
),
)
How can I have a Card that tightly wraps a Column
of widgets?
Upvotes: 76
Views: 67338
Reputation: 12233
For some reason mainAxisSize: min
never seemed to work. I always got the stupid error that it didn't know what to do. To fix, I just resorted to ListView with shrinkWrap: true
return ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(0),
// background is red
children: [
...
]
)
Upvotes: 1
Reputation: 1078
If Row or Column is your root widget,
use MainAxisSize.min
on root widget.
If Another widget is the root, then
wrap that root widget in Center
widget.
Upvotes: 2
Reputation: 34220
Wrap widget may come to rescue if anyone wants to shrink its list, which exacts similar to @Adam answer
body: Container(
child: Card(
child: Wrap(
direction: Axis.vertical,
spacing: 10,
children: <Widget>[
Text('One'),
Text('Two'),
Text('Three'),
Text('Four'),
],
),
),
),
but this Wrap can do the job of both Row & Column if you add Column for Axis.vertical & Row for Axis.Horizontal. Also you can add equal spacing to all inbetween widgets which is missing in Column & Row
Upvotes: 9
Reputation: 1789
By default, Column
expands to fill the maximum vertical space. You can change this behavior by setting the mainAxisSize
property to MainAxisSize.min
, which causes the Column
to take up only the minimum amount of vertical space it needs to fit its children.
Upvotes: 169