BoxConstraints Error when stretching a row widget - flutter

I have a Card widget in a ListView widget and the card has the following code structure to it:
return Card(
child: Row(
// crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Image(
image: AssetImage('assets/images/my-img.jpg'),
width: 150,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, // THIS HAS NO EFFECT
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(content.title),
Text(content.description),
],
),
Row(
// crossAxisAlignment: CrossAxisAlignment.baseline,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.accessibility),
Text('cool')
],
),
Text('something else'),
],
)
],
),
),
],
),
);
I'm trying to make the column in the row have a spaceBetween alignment since right now it the column is vertically centered. I tried adding a CrossAxisAlignment.stretch to the Row widget, but I get an error:
BoxConstraints forces an infinite height

You could add a SizedBox between the Column and Row.
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(content.title),
Text(content.description),
],
),
//Sized Box
SizedBox(height: //whatever double),
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.accessibility),
Text('cool')
],
),
Text('something else'),
],
)

Columns take all the available height. Consider wrapping the Column inside Expanded with a Container of fixed height.
To make a Column take as much space as possible, set mainAxisSize: MainAxisSize.min. However all the widgets are packed up and all Alignments will have no effect.
So probably what you are looking for is to set the height of the Row with the the maximum height of its children widgets. This can be achieved by wrapping the Row with IntrinsicHeight.
Card(
child: IntrinsicHeight(
child: Row(
// ...
),
),
),

Related

Flutter Container Match Parent inside Column

I am quite a newbie in Flutter.
I tried several pieces of stuff but I failed at the end.
I have a row and this row contains two different columns.
My question is I am trying to add Container which matches the parent until other columns height into the first column.
I already tried widgets like Flex, Expanded etc. And I got infinity error. Since the first column has no idea about other columns size.
Widget _buildProgressVideoCall() {
return Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
CircleAvatar(
child: Image.asset(
ImageAssets.videocall,
scale: 3.0,
),
radius: 22,
SizedBox(height: 16),
Expanded(child: Container(
child: Image.asset(
ImageAssets.progressDots,
repeat: ImageRepeat.repeatY,
)))
],
),
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.only(left: 16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[ // Fixed Height Widgets Buttons etc.
],
),
),
),
],
);
}
If I have your setup right try doing this I might not have it quite right let me know if I misunderstand what you want.
Row(
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[],
),
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(),
],
)
],
),

Positioning widgets within ListView

This is what I want to do. Form is a Column with a few TextField-s that have to be in the middle of the screen. Footer is another Column with a single Text widget but positioned at the bottom of the screen. Both columns are in a Stack. It looks fine when Form is small but if its height is more than screen height (for example, when the keyboard is open) I cannot scroll to view the whole Form and Footer appears above everything.
Scaffold(
body: Container(
padding: EdgeInsets.all(20.0),
constraints: BoxConstraints.expand(),
child: Center(
child: Stack(
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
// Form
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
// Footer
),
],
),
),
),
);
So I decided to put them in ListView instead of Stack. The scrolling problem is already fixed but now positioning is not correct - they are on the top. How to put Form into the center and Footer at the bottom?
Scaffold(
body: Container(
padding: EdgeInsets.all(20.0),
constraints: BoxConstraints.expand(),
child: Center(
child: ListView(
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
// Form
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
// Footer
),
],
),
),
),
);

How to strech a column while centering their children

I want to expand a column horizontally while keeping the children (an icon and a text) in the center.
When I use CrossAxisAlignment.center it doesn't mathes its parents width. So I tried CrossAxisAlignment.stretch.
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.help),
Text('Please help!'),
],
),
Here the text was aligned left even though the icon is centerd.
I do not understand this and a solution would be highly appreciated.
have you tried wrapping column in a container and setting width to double.infinity?
Container(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.help),
Text('Please help!'),
],
),
)
I found a hack might not the exact solution but works for me.
there might be other solutions
Added a SizedBox box widget with width because we need to center horizontally.
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.help),
Text('Please help!'),
SizedBox(
width: double.infinity, // it will take entire available device width
height: 0,
)
],
),
Another way.
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Container(),
),
Icon(
Icons.help,
color: Colors.white,
),
Expanded(
child: Container(),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Container(),
),
Text('Please help!'),
Expanded(
child: Container(),
),
],
)
],
)
The right way to do is:
Center( // it helps column stretch
child: Column(
mainAxisAlignment: MainAxisAlignment.center, // it helps child stay in center
children: ...,
)
)

Space text in row but only based on one child widget

So I want to create this:
| 12 5 300 |
| monkeys baboons chimpanzees |
Basically, put the widgets in a Row and use mainAxisAlignment: MainAxisAlignment.spaceAround on the numbers. The problem is, the text is disrupting the spacing, and since 'chimpanzees' is longer, it causes the 5 baboons to be off center. What is the best way to have the spaceAround only align the numbers, then center the text underneath the numbers?
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Column(
children: <Widget>[
Text('12'),
Text('monkeys'),
],
),
Column(
children: <Widget>[
Text('5'),
Text('baboons'),
],
),
Column(
children: <Widget>[
Text('300'),
Text('chimpanzees'),
],
),
],
),
You can try to use Expanded() to have same width for the Row() children. No need to use spaceAround.
Row(
children: <Widget>[
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('12'),
Text('monkeys'),
],
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('5'),
Text('baboons'),
],
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('300'),
Text('chimpanzees'),
],
),
),
],
),
Try this
mainAxisAlignment: MainAxisAlignment.spaceEvenly,

Flutter align two items on extremes - one on the left and one on the right

I am trying to align two items at extremes one on the left and one on the right.
I have one row that is aligned to the left and then a child of that row is aligned to the right. However it seems the child row is picking up the alignment property from its parent. This is my code
var SettingsRow = new Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text("Right",softWrap: true,),
],
);
var nameRow = new Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text("Left"),
SettingsRow,
],
);
as a result I get something like this
Left Right
What I would like is
Left Right
Also there is enough space on the Row. My question is why is the child Row not exhibiting its MainAxisAlignment.end property ?
Use a single Row instead, with mainAxisAlignment: MainAxisAlignment.spaceBetween.
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
new Text("left"),
new Text("right")
]
);
Or you can use Expanded
new Row(
children: [
new Text("left"),
new Expanded(
child: settingsRow,
),
],
);
A simple solution would be to use Spacer() between the two widgets
Row(
children: [
Text("left"),
Spacer(),
Text("right")
]
);
You can do it in many ways.
Using mainAxisAlignment: MainAxisAlignment.spaceBetween
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FlutterLogo(),
FlutterLogo(),
],
);
Using Spacer
Row(
children: <Widget>[
FlutterLogo(),
Spacer(),
FlutterLogo(),
],
);
Using Expanded
Row(
children: <Widget>[
FlutterLogo(),
Expanded(child: SizedBox()),
FlutterLogo(),
],
);
Using Flexible
Row(
children: <Widget>[
FlutterLogo(),
Flexible(fit: FlexFit.tight, child: SizedBox()),
FlutterLogo(),
],
);
Output:
Yes CopsOnRoad is right, through stack you can align one on right and other at center.
Stack(
children: [
Align(
alignment: Alignment.centerRight,
child: Text("right"),
),
Align(
alignment: Alignment.center,
child: Text("center"),
)
],
)
I had multiple entries in my row, and the accepted answer didn't work for me.
I needed to wrap the final entry in an Align.
I had :
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
...allMyLeftAlignedChildren,
Expanded(
child: myRightAlignedChild,
And I needed :
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
...allMyLeftAlignedChildren,
Expanded(
child: Align( // <--- these 2 lines fixed it
alignment: Alignment.centerRight, // <--- these 2 lines fixed it
child: myRightAlignedChild,
use the line of code mainAxisAlignment: MainAxisAlignment.spaceBetween, in a Row. That will allow The widgets to be on two extremes. However if you are working on TextField, use decoration class and the attribute prefix*** and suffix*** instead
Using Flexing Widget
Row(
children: [
Text(
'1',
style: TextStyle(
fontSize: 18, color: Colors.black),
),
Flexible(fit: FlexFit.tight, child: SizedBox()),
Text(
'10',
style: TextStyle(
fontSize: 18, color: Colors.black),
),
],
),