I am trying to center a group of objects within a row using Flutter/Dart. I have tried various methods and all have failed. I want the icon to be to the left of the screen and the remaining variables (trips, followers, and following) to be centered in the remaining space. I have tried it a variety of ways using the MainAxisAlignment and CrossAxisAlignment classes based on some solutions I found on SO but none have worked. What am I doing wrong?
Column(
children: <Widget>[
ClipOval(
child: Material(
color: Colors.grey, // button color
child: InkWell(
child: SizedBox(
width: 80,
height: 80,
child: Align(
alignment: Alignment.center,
child: Icon(
Icons.person,
size: 65.0,
),
),
),
),
),
)
],
),
Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
trips, followers, following,
],
),
],
),
Image 1: How it currently looks
Image 2: Flutter Inspector View
You want to evenly distribute the space right from the icon between the three texts, right?
I would solve this by wrapping the 3 widgets in another row for the rest of the space without the icon and then wrapp the Text in an expanded widget that fills the rest of the space.
i assume that trips, followers and following are columns.
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Column(
children: <Widget>[
ClipOval(
....(your stuff)
)
]
),
Row(
children: <Widget>[
Expanded(
child: trips
),
Expanded(
child: followers
),
Expanded(
child: following
),
]
)
]
) //Row End
In the Row documentation you can see how the expanded takes a third of the available space. [1]
Related
I have a problem with building a specific layout in flutter.
What I need is:
Scrollable screen, with two columns, where the first col is of certian (but dynamic) height. And the second col has part of certain (but dynamic) height and the rest of the col I want to fill remaining space.
The code structure.
Row(
children: [
Expanded(
child: Column(children:[
someDynamicHeightWidgetsHere()])),
Expanded(child: Column(children: [
someWidgetsHere(),
here fill remainind space to match the first column]))
]
)
Use IntrinsicHeight, This widget only expands to its child height.
This class is useful, for example, when unlimited height is available and
you would like a child that would otherwise attempt to expand infinitely to
instead size itself to a more reasonable height.
Example:
IntrinsicHeight(
child: Row(
children: [
Expanded(
child: Column(
children: [
Container(
height: 800,
color: Colors.blue,
),
],
),
),
Expanded(
child: Column(
children: [
Container(
height: 400,
color: Colors.red,
),
Expanded(
child: Container(
color: Colors.yellow,
),
),
],
),
),
],
),
Output:
I'm trying to get working the MainAxisAlignment property on the Column, but it's not working quite expected. Here is my code.
Scaffold(
appBar: AppBar(
title: Text('Account'),
),
body: Container(
child: Column(
children: <Widget>[
Card(
margin: EdgeInsets.only(left: 0.0, right: 0.0, top: 0.0, bottom: 20.0),
child: InkWell(
onTap: () {},
child: Padding(
padding: EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Image.network(
'https://cdn.mydomain.com/Color/PNG/512/profile-512.png',
height: 72.0,
),
SizedBox(width: 8.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround, // <<<=== this line
children: <Widget>[
Text('User\'s display name'),
Text('user#company.com'),
],
)
],
),
),
),
)
],
),
),
)
My hierarchy is Container->Column->Card->InkWell->Row->Column. The innermost Column widget has a problem. I figured out that If I remove the first Column widget then the MainAxisAlignment just works fine.
But I can't do that as I want to build a Column layout with various Cards inside it, as you can see in the code.
Could somebody please let me know what is this weird behaviour and a solution around this?
Regards.
Try to wrap this column in a Container or SizedBox and set a double.infinity height for it.
The problem that's happening it's because a Column or any component which you don't set a height or width, will automatically adjust to the widgets inside of it.
Container(
height: MediaQuery.of(context).size.height, //Add here
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text('User\'s display name'),
Text('user#company.com'),
],
),
),
OBS: I personally like to use MediaQuery for this. eg: MediaQuery.of(context).size.height to get the full height of the device, then, you can manipulate it, dividing by 2, 3, subtracting...
I am trying to use space between to separate two Text widgets but none of mainAxisAlignment options works.
Screenshot of code below.
In the picture, you can see Text2 and Text3 are glued together I want them separated. First child in main Row needs to be expanded 1. Second (the problematic one) needs to be like expanded 0.
Container(
color: Colors.blue,
child: Row(
children: [
Expanded(
child: Container(
color: Colors.orange,
child: Text('Text1'),
),
flex: 1,
),
Column(
children: [
Row(
children: [Text('Text2'), Text('Text3')],
),
Text('Long text Long text Long text'),
],
)
],
),
)
so I realized you used Expanded widget for the first child but not for the second. Also, you need to add mainAxisAlignment: MainAxisAlignment.spaceBetween to the Row widget. Below is a complete code for what you want to achieve.
Container(
color: Colors.blue,
child: Row(
children: [
Expanded(
child: Container(
color: Colors.orange,
child: Text('Text1'),
),
flex: 1,
),
Expanded(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Text2'),
Text('Text3')
],
),
Text('Long text Long text Long text'),
],
),
)
],
),
)
Use mainAxisAlignment to spaceBetween
Row(
mainAxisAlignment:MainAxisAlignment.spaceBetween,
children: [Text('Text2'), Text('Text3')],
),
Use Spacer() between two Text.
Text("Text2"),
Spacer(),
Text("Text3")
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!
In my layout I have two Widgets in a row, one text and the an icon.
As shown below, assume that * refers to the icon, and using "-" to represent the row:
----------------------------
Text *
----------------------------
How do I make my text centered in the entire row, and the icon to the right end ?
The main thing you need to notice is that if you don't want to use Stack you should provide same width-consuming widgets both on left and right.
I would do this with either Expanded and Padding
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 32.0),
child: Text(
"Text",
textAlign: TextAlign.center,
),
),
),
Icon(Icons.add, size: 32.0,)
],
)
or with Row's mainAxisAlignment and a SizedBox
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
const SizedBox(width: 32.0),
Text("Text"),
Icon(Icons.add, size: 32.0)
],
)
or with Expanded and a SizedBox on the left instead of the padding :). The padding or extra container on the left is so that the textAlign will truly center the text in the row taking into account the space taken up by the Icon.
Simply use Expanded and Spacer widgets on left/right side and put your widget inside the Expanded:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Spacer(),
Text('Text'),
Expanded(
child: Text('*'),
),
),
],
),
Result:
1. Using Row (not very flexible though)
Row(
children: <Widget>[
Expanded(child: Center(child: Text('Center'))),
Text("#"),
],
)
2. Using Stack (flexible)
IntrinsicHeight(
child: Stack(
children: [
Align(child: Text('Center')),
Positioned(right: 0, child: Text('#')),
],
),
)
I found it necessary to use a Stack to get Text to be truly centered:
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.center,
child: Text('Text'),
),
Align(
alignment: Alignment.centerRight,
child: Text('*'),
)
],
),
],
);
For flexibility reasons I recommend to use Expanded widgets:
Row(
children: [
Expanded(flex: 1, child: Container()),
Expanded(
flex: 8,
child: Text('Your Text',
textAlign: TextAlign.center,
),
),
Expanded(flex: 1, child: IconButton(...))
],
)
For my case, I solved my centering problem by adjusting the flex property of the Spacer widget -
Row(children: [
Spacer(flex: 3),//3 was for my case, It might be changed for your widgets
Text('Center'),
Spacer(flex: 1),//1 was also for my case, It might be changed on for your widgets
Text("*")]);
Add another icon in the start and set the opacity to zero.
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CloseButton(
onPressed: () => Navigator.of(context).pop(),
),
Text('text',),
Opacity(
opacity: 0,
child: Icon(Icons.close),
),
],
)
This worked for me without Stack. But it is the other way around. "Text" goes to left "*" goes to center:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Text("text",
style: Theme.of(context).textTheme.caption),
),
Text("*"),
Spacer(),
],
)