Flutter nested Rows MainAxisAlignment - flutter

I want to do this :
But here is what I actually got :
Here is my code :
Row itemTransaction(BuildContext context, Transaction transaction) {
/// This is the function that will build each item of our transaction list.
return new Row(
children: <Widget>[
new Container(
width: MediaQuery.of(context).size.width / 6,
height: MediaQuery.of(context).size.width / 6,
child: new Image.asset(
(transaction.sent) ? "images/tx_output.png" : "images/tx_input.png",
),
),
new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
discoderyText("test"),
discoderyText("test 2"),
],
),
discoderyText("SOME HASH KEY"),
],
),
],
);
}
The discoderyText is basically a custom text (i.e. with colors).
As you can see, there is mainAxisAlignment: MainAxisAlignment.spaceBetween set for my Row, so test and test2 should be on opposite sides.
When I remove the image and I only returns a Row that contains two Text, and I set the mainAxisAlignment, it works. It seems like nested rows can NOT use this variable.
Here is basically the plan of my view :

Screenshot
Row(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width / 6,
height: MediaQuery.of(context).size.width / 6,
child: CircleAvatar(backgroundImage: AssetImage(chocolateImage),),
),
Expanded( // add this
child: Padding(
padding: const EdgeInsets.all(8.0), // give some padding
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min, // set it to min
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text("test"),
Text("test 2"),
],
),
Text("SOME HASH KEY HERE"),
],
),
),
),
],
)

Related

Align image and text in center in GridView in flutter

I am trying to align image and text in the center, it works when text is small but when i have large text then everything changes. I am using GridView which has 3 items on each row..
Widget buildItems(BuildContext context, String impagepath, String modulename) {
return Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: CustomButtonWidget(
image: impagepath,
size: 100,
borderWidth: 5,
onTap: () {}
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: double.infinity,
height: double.infinity,
child: Text("${selectlang.getAlbum(modulename, lang_selection)}"),
),
],
)
],
);
}
You need to use CrossAxisAlignment property of Column` widget
Use crossAxisAlignment: CrossAxisAlignment.center, in your Column widgets
Widget buildItems(BuildContext context, String impagepath, String modulename) {
return Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: CustomButtonWidget(
image: impagepath,
size: 100,
borderWidth: 5,
onTap: () {}
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: double.infinity,
height: double.infinity,
child: Text("${selectlang.getAlbum(modulename, lang_selection)}"),
),
],
)
],
);
}
use crossAxisAlignment: CrossAxisAlignment.center inside column widget.

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

MainAxisAlignment.spaceEvenly not working

I tried to align the buttons and here is the result. I am trying the get the 3 buttons (left, down, right) to space evenly using MainAxisAlignment.SpaceEvenly, but some how they still stick together. Can someone point out for me the problem behind this and how to achieve the result I want?
Here is the result
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// 4 Buttons on left side
new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Up button
new Row(
children: <Widget>[
MovingButton(
name: new Text("Up"),
channel: this.channel,
),
],
),
// 3 buttons that stick and needed to be space evenly
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
MovingButton(
name: new Text("Left"),
channel: this.channel,
),
MovingButton(
name: new Text("Down"),
channel: this.channel,
),
MovingButton(
name: new Text("Right"),
channel: this.channel,
),
],
),
],
),
// attack button
new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
MovingButton(
name: new Text("Attack"),
channel: this.channel,
),
],
),
],
),
Well if I did understand what you need, you have various options.
You can expand your first column inside the outer row, but this way you sould have the second column all to the right (you need some padding here I guess).
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// 4 Buttons on left side
Expanded(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Up button
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: new Text("Up"),
),
],
),
// 3 buttons that stick and needed to be space evenly
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
child: new Text("left"),
),
RaisedButton(
child: new Text("Down"),
),
RaisedButton(child: new Text("Right")),
],
),
],
),
),
// attack button
new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(child: new Text("Attack")),
],
),
],
),
I suggest you to use Flutter Outline panel to have a clue of your render tree.
And this is your actual situation without expanding the first column:
Or you could simply add padding to your buttons (used RaiseButton instead of your custom MovingButton to test it, but you use your MovingButton instead)
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// 4 Buttons on left side
new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Up button
new Row(
children: <Widget>[
RaisedButton(
child: new Text("Up"),
),
],
),
// 3 buttons that stick and needed to be space evenly
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 2),
child: RaisedButton(
child: new Text("left"),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 2),
child: RaisedButton(
child: new Text("Down"),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 2),
child: RaisedButton(
child: new Text("Right")
),
),
],
),
],
),
// attack button
new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
child: new Text("Attack")
),
],
),
],
),
or use a ButtonBar instead of a Row widget and add a theme for all your button.
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// 4 Buttons on left side
new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Up button
new Row(
children: <Widget>[
RaisedButton(
child: new Text("Up"),
),
],
),
// 3 buttons that stick and needed to be space evenly
new ButtonTheme(
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 8),
child: new ButtonBar(
children: <Widget>[
RaisedButton(
child: new Text("left"),
),
RaisedButton(
child: new Text("Down"),
),
RaisedButton(
child: new Text("Right")
),
],
),
),
],
),
// attack button
new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
child: new Text("Attack")
),
],
),
],
),
put the children widgets of your buttons row inside containers, this worked for me in similar cases

Flutter put row into row

I need to create the following:
I could do it with code:
Row(
children: <Widget>[
Container(
width: 30
),
Column(
children: <Widget>[
Text("label"),
Container(
width: screenSize.width - 30, // <- this is problem
child: Row(
children: <Widget>[
Expanded( child: TextField() ),
Expanded( child: TextField() ),
],
),
),
],
),
],
);
Is it possible to do it in a different way, namely the line width: screenSize.width - 30?
You can use crossAxisAlignment inside Column widget and make it Stretch to get all remaining width in screen
Row(
children: <Widget>[
Container(
width: 30
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // <- Add this
children: <Widget>[
Text("label"),
Container(
child: Row(
children: <Widget>[
Expanded( child: TextField() ),
Expanded( child: TextField() ),
],
),
),
],
),],);
[Please read official flutter documentation of Column widget]
Column Widget
CrossAxisAlignment
Solution
Row(
children: <Widget>[
Container(
color: Colors.red,
width: 50,
),
Expanded(
child: Column(
children: <Widget>[
Text("label"),
Expanded(
child: Row(
children: <Widget>[
Expanded(
child: TextField()
),
Expanded(
child: TextField()
),
],
),
),
],
),
),
],
);
Explanation
It is about where you place Expanded instances.
You have a row, which can fill its parent if it included an Expanded child. So we defined the size of one of its children (Container), and the other is simply Expanded. The same goes for the Column child ..
Maybe starting with a simpler example makes it easier to understand. Please refer to this useful answer.
Output
P.S. Welcome to StackOverFlow, Dmitry!

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