Flutter Container Match Parent inside Column - flutter

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

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

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 row mainAxisAlignment spaceBetween not working

This is my code to build the item view container:
Widget buildItemView(InboxItem t) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => print("ontap")),
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(padding: EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 10.0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
icon ...
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
/// title
_buildTitle(t),
...
],
)
],
)),
Divider(height: 3.0)
],
),
);
}
and _buildTitle code, here is where the problem occurs:
Widget _buildTitle(InboxItem item) {
return Container(
padding: EdgeInsets.only(bottom: 2.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
/// sender
Text(item.sender == null ? "" : item.sender, style: ltBlackLargeText),
/// time
Text(item.receiveTime == null ? "" : item.receiveTime,
style: dkGreySmallText),
],
),
);
}
Run result, time is immediately after the username instead of the right.
This is part of the screenshot:
Where is the problem?
Because the superior does not fill the remaining space, change the item view code:
Widget buildItemView(InboxItem t) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => print("ontap")),
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(padding: EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 10.0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
icon ...
),
Expanded(
child:Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
/// title
_buildTitle(t),
...
],
) ,
)
],
)),
Divider(height: 3.0)
],
),
);
}
Wrap Column Widget with Expanded inside Row as below,
Row(
children: [
Image.asset("assets/..."),
Expanded(
child: Column(children: [
Row(
children: [
Text("admin"),
Text("2020-12-14"),
],
),
]),
),
],
)
See this image
Wrap your row in the SizedBox widget and set your desired width. Inside the column widget, the row is not getting enough width to apply mainAxisAlignment: MAinAxisAlignment.spaceBetween.
Row(
children: [
// avatar image
const CircleAvatar(
backgroundColor: Colors.yellow,
radius: 45,
),
const SizedBox(width: 10),
// for side details
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// for first row using spaceBetween
SizedBox(
width: MediaQuery.of(context).size.width * 0.6,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text('admin'),
Text('20-10-2020'),
],
),
),
// other details
const SizedBox(height: 10),
const Text('123'),
const SizedBox(height: 10),
const Text('12312'),
],
),
],
),
You don't need to these three lines;
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
Just use Spacer() to push the next item to the end of empty space. Here is your final code;
Widget _buildTitle(InboxItem item) {
return Container(
padding: EdgeInsets.only(bottom: 2.0),
child: Row(
children: <Widget>[
/// sender
Text(item.sender == null ? "" : item.sender, style: ltBlackLargeText),
Spacer(),
/// time
Text(item.receiveTime == null ? "" : item.receiveTime,
style: dkGreySmallText),
],
),
);
}

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