How to strech a column while centering their children - flutter

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: ...,
)
)

Related

BoxConstraints Error when stretching a row widget

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(
// ...
),
),
),

In flutter, I want the Icon within a container to take up maximum size of the container

Widget build(BuildContext context) {
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Flexible(
flex: 1,
child: Container(
color: Colors.blueAccent
),
),
Flexible(
flex: 4,
child: Container(
color: Colors.deepOrangeAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
//mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Icon(Icons.image),
],
),
),
),
Flexible(
flex: 2,
child: Container(color: Colors.blueGrey),
),
],
),
);
Screenshot
The Icon is taking its original size only. I want it to fill the container.
I have tried LayoutBuilder but the BoxConstraints have infinite height warning comes.
Please suggest any other options without using hardcoded sizes for any of the widgets.
Edit; So after reading your comment here is you should use a FittedBox instead (as suggested in the comments) and BoxFit.Fill property; so:
<Widget>[ Expanded(child:FittedBox(child: Icon(Icons.image),fit: BoxFit.fill)), ]
--
If you can change your icon to Image then you can use the BoxFit.fill property to stretch the image to fill the entire container (wrap the image in Expanded widget too).
Here is an example with a placeholder:
Flexible(
flex: 4,
child: Container(
color: Colors.deepOrangeAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
//mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(child: Image.network('https://picsum.photos/250?image=9', fit:BoxFit.fill)
)
],
),
),
I would take the LayoutBuilder approach. You mentioned you had infinity warning, which might be because you don't dynamically pick between the height of your parent container or its width.
Depending on the orientation of your device, you might need to pick one or the other. The easiest way to cater for that is to pick the smaller of the two.
Widget build(BuildContext context) {
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Flexible(
flex: 1,
child: Container(color: Colors.blueAccent),
),
Flexible(
flex: 4,
child: Container(
color: Colors.deepOrangeAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
//mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
LayoutBuilder(builder: (context, constraints) {
var height = constraints.maxHeight;
var width = constraints.maxWidth;
return Icon(FontAwesomeIcons.addressBook, size: min(height, width));
}),
],
),
),
),
Flexible(
flex: 2,
child: Container(color: Colors.blueGrey),
),
],
),
);
}
}
Note: you'll need to import the 'dart:math' package to use the min() function.

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(),
],
)
],
),

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),
),
],
),