Is there a way to achieve this layout with flutter? With one Column expanded, and the other Column shrink to fit the texts inside, within a Row.
I'm from a web background, I know I can do it with Flex-grow and Flex-shring along with whitespace:nowrap.
I would like to achieve this layout
But in flutter I tried:
- This will give me two equal width columns:
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [Text('Monthly Membership'), Text('Subscription')],
),
),
Flexible(
fit: FlexFit.tight,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
Text(
' 100',
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
),
Text(
'18 Sept 2021',
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
),
],
),
),
],
);
- This will give an error.
RenderBox was not laid out: RenderFlex#3024f relayoutBoundary=up1 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [Text('Monthly Membership'), Text('Subscription')],
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
Text(
' 100',
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
),
Text(
'18 Sept 2021',
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
),
],
),
],
);
CodePudding user response:
Your code-snippet just works fine, just missing alignment.
About your desire UI, you just need to set alignment.
Card(
color: Colors.grey,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: const [
Text('Monthly Membership'),
SizedBox(height: 10),
Text('Subscription'),
],
),
),
),
Flexible(
fit: FlexFit.tight,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: const [
Text(
' 100',
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
),
SizedBox(height: 10),
Text(
'18 Sept 2021',
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
),
],
),
),
),
],
),
),
CodePudding user response:
Your second attempt fails because CrossAxisAlignment.stretch
takes all of the horizontal space available, but a Row
gives its children an unbounded width constraint. This forces the column to have infinite width, which is impossible. There are two options to fix this:
- Use a different
crossAxisAlignment
This will make each child of the Column
take as much space as it's going to take. Based on your image, you probably want CrossAxisAlignment.center
, which will center the column's children. The column will take its width from the larger of the two Text widgets.
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
// ...
- Use
IntrinsicWidth
IntrinsicWidth
will measure the width that the Column wants to be, then give it that width. This will give the Column
a tight width constraint in a second layout pass, which will make CrossAxisAlignment.stretch
work as intended.
IntrinsicWidth(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
// ...
Both options will layout the second column with unbounded width, which means that if you have very long text, it might make the first column very small. If you want to bound the width of the column, you can add a ConstrainedBox
to either solution.
CodePudding user response:
BoxConstraints forces an infinite width.
hasSize
"RenderBox was not laid out: RenderFlex#c927e relayoutBoundary=up1 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE" - that means the second column
doesn't get any width, that's you need to set fixed height or Expand
your widget.
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [Text('Monthly Membership',), Text('Subscription')],
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
' 100',
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
),
Text(
'18 Sept 2021',
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
),
],
),
),
],
)
And for more about flexible
and Expand
read this article