How to properly align widgets using flex property in flutter - flutter

I'm trying to make a footer and I want everything to appear Centered with even space between these three widgets in the below code.
Container(
margin: const EdgeInsets.symmetric(vertical: 20, horizontal: 40),
child: Row(
children: <Widget>[
const Expanded(
flex: 1,
child: Text(
'All Right Reserved',
style: TextStyle(fontSize: 10),
)),
Expanded(
flex: 3,
child: Row(
children: <Widget>[
FooterItem(
title: 'Twitter',
onTap: () {},
),
FooterItem(
title: 'Instagram',
onTap: () {},
),
FooterItem(
title: 'WhatsApp',
onTap: () {},
),
],
),
),
const Expanded(
flex: 1,
child: Text(
'All Right Reserved',
style: TextStyle(fontSize: 10),
)),
],
),
)
I tried using flex as seen in the above code but it doesn't align at the center and no even space as seen in the below screenshot. How to fix this?

You can remove all Expanded and use mainAxisAlignment in parent Row:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[]
)

Related

flutter box constraints not propagating to child as expected

I have learned that to make a Text wrap, you have to wrap it inside a Flexible() and set softWrap: true.
I have a ListView() with items generated by the following code:
return Container(
constraints: const BoxConstraints(maxWidth: 300),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Checkbox(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap),
GestureDetector(
onTap: () {},
child: Container(
color: Colors.white,
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(getCustomIcon(name: f.icon), size: 20, color: Colors.black),
const SizedBox(width: 6),
Flexible(
child: Text(f.name,
softWrap: true, style: TextStyle(fontSize: 14))),
const SizedBox(width: 6),
]),
))
]),
);
The Container should have a maximum width of 300 (see the outer BoxConstraints), but the innermost Text() node does not wrap and overflows.
Somewhere in here the box constraints get lost, but I don't understand where.
Note: I removed UI non-relevant code like onTap/onChange/...
After some more testing around I was able to solve the problem myself.
The problem is wrapping a row inside a row (even with other containers in-between) removes the constraints.
The solution is to put a Flexible/Expanded as the child of the parent row:
// innerRow is unconstrained
Row( children: [
...otherElements,
Row() // innerRow
]);
// innerRow is constrained
Row( children: [
...otherElements,
Flexible( // Flexible or Expanded tells the child to fill in the remaining space.
child: Row() // innerRow
)
]);
try :
Wrap your Container with either Row() or Center().
here is Code :
return Center(
child: Container(
constraints: const BoxConstraints(maxWidth: 300),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Checkbox(
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
onChanged: (bool? value) {},
value: true,
),
GestureDetector(
onTap: () {},
child: Container(
color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.abc,
size: 20, color: Colors.black),
const SizedBox(width: 6),
Flexible(
child: Text("f.name",
softWrap: true,
style: TextStyle(fontSize: 14))),
const SizedBox(width: 6),
]),
))
]),
),
);

Why Third Row widget in the Column stack goes away?

I am building the app where my widget tree starts with Scaffold and as for body parameter, I assign the column widget. Within the column widget, I want the first 3 buttons sitting side by side, which work fine and next Expanded Widget which takes whole screen and third again 2 buttons sitting side by side. However, the thing is that, the third row widget is not visible on the screen of the phone. Can someone explain why it happens?
Scaffold(
appBar: AppBar(
title: const Text("My Work Timer"),
),
body: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Padding(padding: EdgeInsets.all(defaultPadding)),
Expanded(
child: ProductivityButton(
color: const Color(0xff009688),
text: "Work",
size: 3,
onPressed: () {}),
),
Padding(padding: EdgeInsets.all(defaultPadding)),
Expanded(
child: ProductivityButton(
color: const Color(0xff607D8B),
text: "Short Break",
size: 3,
onPressed: () {}),
),
Padding(padding: EdgeInsets.all(defaultPadding)),
Expanded(
child: ProductivityButton(
color: const Color(0xff455A64),
text: "Long Break",
size: 3,
onPressed: () {}),
),
Padding(padding: EdgeInsets.all(defaultPadding)),
],
),
Expanded(
child: Text("Hello"),
),
Row(
children: [
Padding(padding: EdgeInsets.all(defaultPadding)),
Expanded(
child: ProductivityButton(
color: const Color(0xff212121),
size: 2,
text: "Stop",
onPressed: () {},
)),
Padding(padding: EdgeInsets.all(defaultPadding)),
Expanded(
child: ProductivityButton(
color: const Color(0xff009688),
size: 2,
text: "Restart",
onPressed: () {},
)),
Padding(padding: EdgeInsets.all(defaultPadding)),
],
)
],
),
);
regards

Flutter: cutting a row in "half"

I've been toying with lists in flutter, and everything is fine. I'm starting to understand the logic of the whole thing.
Now I wanted to do a simple layout like that :
My problem is that I can't find a way to make the first row. I tried to tell Row to let its two children take half and no less no more, but I didn't really find a way. (The inside thing will eventually be buttons.)I tried several things to no avail. Here is the layout I started from :
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 50.0),
),
Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
top: buttonPaddingTop,
left: buttonPaddingSide,
right: buttonPaddingSide),
child: ButtonTheme(
child: FlatButton(
onPressed: () {},
color: Colors.grey,
child: const Text('LARGE TEXT',
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: buttonFontSize)),
),
),
),
Padding(
padding: EdgeInsets.only(
top: buttonPaddingTop,
left: buttonPaddingSide,
right: buttonPaddingSide),
child: ButtonTheme(
child: FlatButton(
onPressed: () {},
color: Colors.grey,
child: const Text('LARGE TEXT',
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: buttonFontSize)),
),
),
),
],
),
]),
),
);
}
Should I continue trying like this, or should I try another object than Row to arrange the layout ?
Expanded takes as much space as available in this case horizontally. That means if you would use 2 Expanded widgets inside your Row, the space will be divided by half.
Try this:
Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Text('first half'),
),
Expanded(
child: Text('second half'),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Text('first half'),
),
Expanded(
child: Text('second half'),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Text('full width'),
)
],
),
],
)
Make sure you read more about Flutter widgets, for example watch this video (and other ones in this series):
https://www.youtube.com/watch?v=_rnZaagadyo

How to remove the space between rows in card (Flutter)

I used a card widget in my flutter App that has two rows, the problem that I have is a large space appeared between the two rows as you can see in the following image
how can fix this problem ?
my code that i tried it here :
return Card(
child: Container(
alignment: FractionalOffset.center,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
child: ListTile(
title: Text(snapshot.data[index].data["title"],
textDirection: TextDirection.rtl,
style: TextStyle(fontSize: 14.0,
fontFamily: 'Cairo',
fontWeight: FontWeight.bold),),
onTap: () => navigateToDetails(snapshot.data[index]),
),
),
),
//SizedBox(width: 1.0),
Expanded(
flex: 1,
child: Container(child: Image.network(snapshot.data[index].data["image_url"],height: 80.0,width: 80.0)),
),
],
),
),
);
add MainAxisAlignment:MainAxisAlignment.center property to your Row widget
followed code should work for you check this out.
return Card(
child: Container(
alignment: FractionalOffset.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
child: ListTile(
title: Text(
snapshot.data[index].data["title"],
textDirection: TextDirection.rtl,
style: TextStyle(
fontSize: 14.0,
fontFamily: 'Cairo',
fontWeight: FontWeight.bold),
),
onTap: () => navigateToDetails(snapshot.data[index]),
),
),
),
//SizedBox(width: 1.0),
Expanded(
flex: 1,
child: Container(
child: Image.network(snapshot.data[index].data["image_url"],
height: 80.0, width: 80.0)),
),
],
),
),
);
you are using expanded widget inside row so that both the widget try to get same width and also try to cover whole width possible.
so that, if you want to remove space between row widget then remove expanded widget and play with MainAxisAlignment property of Row to arrange or manage the space.
you can use values like:
MainAxisAlignment.spaceBetween and MainAxisAlignment.spaceEvenly

Is there a way to align a widget to the far right of a row in Flutter?

I have a row in Flutter with two widgets. I'm trying to keep the first widget centered in the middle of the screen and the second widget forced to the far right of the screen.
I've tried using Spacer(). This results in the app returning a blank screen.
I've also tried using Expanded. This sends the second widget off the screen completely.
Trying mainAxisAlignment: MainAxisAlignment.spaceBetween did not seem to have any effect.
#override
Widget build(BuildContext context) {
return new Container(
height: MediaQuery.of(context).size.height,
child: SingleChildScrollView(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Container(
child: new GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: Column(
children: <Widget>[
SizedBox(height: 40.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Column(
children: <Widget>[
new Container(
child: Row(
mainAxisAlignment:MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(),
Container(
child: Text(
'Profile',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Lato',
color: Colors.white,
fontSize: 50.0,
fontWeight: FontWeight.w700,
),
),
),
Container(
child: IconButton(
icon: Icon(
Icons.settings,
color: Colors.white,
size: 30.0,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => OnBoarding()),
);
}),
),
]),
),
),
],
),
],
),
You can use a Row with an Expanded child that contains a Stack. Centre your text with Center and position the icon with Positioned, like so:
[...]
child: Column(
children: <Widget>[
SizedBox(height: 40.0),
Row(
children: <Widget>[
Expanded(
child: Stack(
children: [
Center(
child: Text(...),
),
),
Positioned(
right: 8,
child: IconButton(...),
[...]
Simply just add Spacer() between your main text and the Icon you want to the far right.
For example:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
),
Text(
'Random test text',
style: TextStyle(color: Colors.white),
),
Spacer(),
IconButton(
icon: Icon(Icons.more_vert_rounded),
color: Colors.white,
onPressed: () {},
),
],
)
I hope this helps you. And I hope the format of the code is readable. Still getting a hang of stackoverflow comments
I did this and worked in my project
child:Row(
**crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,**
children: [
Icon(MaterialCommunityIcons.comment_outline),
Text("0"),
Icon(Icons.favorite_border),
Text("0"),
],
),
I needed align Icons and Text at right in Row widget
Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end
children: [ // put your widget list and be happy ]
)
)
enter image description here
Use a row with this following structure:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(),
Container(
child: Text(
'Profile',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Lato',
color: Colors.white,
fontSize: 50.0,
fontWeight: FontWeight.w700,
),
),
),
Container(
child: IconButton(
icon: Icon(
Icons.settings,
color: Colors.white,
size: 30.0,
),
),
),
]
),
what will happen is that the spaceBetween property will divide available space equally between the widgets in the row, so I put an empty Container, and this will force the Text widget to be in the middle of the row and the IconButton in the far end as you desire.
I noticed in your code snippet that you have a Column with a single Row which again contains a single Column , you should eliminate this redundancy to optimize your code and make it easier to debug:
Have you tried setting the mainAxisAlignment of the row to mainAxisAlignment.center?
Imo the easiest way to do this is to create a row with 2 children: The first child is an Expanded Row with all your "main" widgets. The second child is your widget which must be aligned to the end.
Row(
children: [
Expanded(
child: Row(
children: [...mainWidgets...],
),
),
...endWidget...
],
),
Note that Expanded is space-greedy. If you use e.g. MainAxisAlignment.center for your Expanded Row, then your children are drawn across the whole avialable width. If this is not to your liking, Id suggest to wrap the Expanded-Row (not Expanded) inside a Container with "constraints: BoxConstraints(maxWidth: 500)". Obviously Expanded shouldnt be Constrained.
Achieve using Expanded & Align like below inside Row:
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
...some other widgets,
Expanded(
//Expanded will help you to cover remaining space of Row
flex: 1,
child: Align(
//Align with alignment.centerRight property will move the child to righteous inside Expanded
alignment: Alignment.centerRight,
child: const Icon(Icons.arrow_back),
),
),
],
),
Note, the Expanded has to be just inside the Row children: <Widget>[],
othewise suppose you've put the GestureDetector inside Row children: <Widget>[], and inside GestureDetector you have put your Expanded, then it won't
work.
Hope this would help many one.