Reputation: 93
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:
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,
),
],
),
),
],
);
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,
),
],
),
],
);
Upvotes: 9
Views: 24220
Reputation: 3435
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:
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,
// ...
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.
Upvotes: 5
Reputation: 63559
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,
),
],
),
),
),
],
),
),
Upvotes: 4