Screenshot of the problem
I am trying to put elements in the red box by having even spaces between each other. (Like giving weight 1 to each of them). To do so, I put "mainAxisAlignment: MainAxisAlignment.spaceEvenly" in parent Column but it is not working.
Container(
margin: EdgeInsets.only(bottom: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
CachedNetworkImage(
imageUrl:
"https://image.tmdb.org/t/p/w500/${movieDetails
.posterPath}",
height: 120.0,
fit: BoxFit.fill),
Expanded(
child: Container(
margin: EdgeInsets.only(left: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, //NOT WORKING!
children: <Widget>[
generateRow(
Strings.released, movieDetails.releaseDate),
generateRow(Strings.runtime,
movieDetails.runtime.toString()),
generateRow(Strings.budget,
movieDetails.budget.toString())
],
)))
],
)),
This is the code for movie image and the red box. I have created a Row which has 2 elements. First one is that image, second one is for red box.
Row generateRow(String key, String value) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[Text(key), Text(value)],
); }
My generateRow method
How can i solve this problem?
As you have given the height to the image is 120.0, can you do the same for the other Container child. By giving this, I was able to achieve what you want.
Code snippet:
Container(
margin: EdgeInsets.only(bottom: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
CachedNetworkImage(
imageUrl:
"https://image.tmdb.org/t/p/w500/${movieDetails
.posterPath}",
height: 120.0,
fit: BoxFit.fill),
Expanded(
child: Container(
height: 120.0 //added to fix
margin: EdgeInsets.only(left: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, //NOT WORKING!
children: <Widget>[
generateRow(
Strings.released, movieDetails.releaseDate),
generateRow(Strings.runtime,
movieDetails.runtime.toString()),
generateRow(Strings.budget,
movieDetails.budget.toString())
],
)))
],
)),
Tips to debug:
I used Flutter Inspector to find the problem. Refer
Refer the image below. Even though we gave Expanded, it occupied just half the size of image. Here the size of Expanded is determined by child's size (which is almost half the image size).
try this :
new Container(
margin: EdgeInsets.only(bottom: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
CachedNetworkImage(
imageUrl:
"https://image.tmdb.org/t/p/w500/${movieDetails
.posterPath}",
height: 120.0,
fit: BoxFit.fill),
Expanded(
child: Container(
margin: EdgeInsets.only(left: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, //NOT WORKING!
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Text("Released : "),
new Text("25-07-2018 "),
],
),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Text("Released : "),
new Text("25-07-2018 "),
],
),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Text("Released : "),
new Text("25-07-2018 "),
],
),
],
)))
],
)),
Another way to achieve the result:
Expanded(
child: Center(
child: // your widget here,
),
)
This one should be the child of the Column, then it will work.
Try looking at this post:
Flutter Layout Row / Column - share width, expand height
Essentially, the image element in the Row makes the row expand in cross axis, but row's actual constraints are not modified. This is why Column's mainAxisAlignment: MainAxisAlignment.spaceEvenly is not working. It needs a parent constraint. And this is achieved with help of IntrinsicHeight. Wrapping Row widget with it will set row's constraints to the largest child's size (which is the image).
Related
Am building a navigation Drawer in flutter, with some items on top and some items on the bottom of the drawer. But in ListView, am unable to add Column widget on the bottom of the Drawer. I had even tried expanded, but that didn't resolved the problem.
Drawer(
child: ListView(
children: <Widget>[
Container(
margin: const EdgeInsets.only(top: 10, right: 10.0, left: 10.0),
padding: const EdgeInsets.only(bottom: 10),
child: Stack(
alignment: Alignment.topRight,
children: <Widget>[
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 30),
CircleAvatar(
radius: 45,
child: Text(
'AC',
style: TextStyle(fontSize: 40),
),
),
],
),
),
],
),
),
Divider(),
Column(children: _drawerOptions),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text(
AppStrings.termsAndConditions,
style: TextStyle(
fontSize: 16.0,
color: Color.fromARGB(255, 39, 39, 39),
),
)
],
),
)
],
),
);
That last widget Column wrapped with Expanded was to put that Column at bottom of the Drawer, but that's not happening.
Can anyone suggest any solution?
You should do it the other way, put ListView inside Column using Expanded , here is the full working code.
Drawer(
child: Column(
children: <Widget>[
Container(
margin: const EdgeInsets.only(top: 10, right: 10.0, left: 10.0),
padding: const EdgeInsets.only(bottom: 10),
child: Stack(
alignment: Alignment.topRight,
children: <Widget>[
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 30),
CircleAvatar(
radius: 45,
child: Text(
'AC',
style: TextStyle(fontSize: 40),
),
),
],
),
),
],
),
),
Divider(),
Expanded(child: ListView(children: _drawerOptions)),
Spacer(),
Text("Terms and conditions"),
],
),
),
The image contains a column of two text widgets which is centered aligned with the icon. But I I'd like the column of text BOTH lines to.... to have one line of text above the centre x axis(of the icon) and one line below.
Here is my code..
Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SvgPicture.asset('assets/icon/but_headphones_${widget.pillarColorNames[program.pillar-1]}.svg',height: 60,),
],
),
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(session.name.toUpperCase(), style: Theme.of(context).textTheme.headline.merge(TextStyle(color: widget.pillarCollors[program.pillar-1])),),
Text(session.description, style: Theme.of(context).textTheme.body1,),
],
),
)
),
Container(
child: Text(duration, style: TextStyle(fontSize: 12, color: Color.fromRGBO(170, 170, 170, 1)),),
),
],
),
EDIT: update code to reflect image
Have you tried setting the text column mainAxisAlignment to spaceBetween?
mainAxisAlignment: MainAxisAlignment.spaceBetween
So your code would be like this:
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(session.name.toUpperCase(), style: Theme.of(context).textTheme.headline.merge(TextStyle(color: widget.pillarCollors[program.pillar-1])),),
Text(session.description, style: Theme.of(context).textTheme.body1,),
],
),
)
),
Another solution would be placing each text widget inside a separate Row and then put a SizedBox between the rows. This way you could manually set the height of the SizedBox to match the space you want between the lines.
I want to align two pieces of text differently, where each piece of text is in a different row but in the same column.
Here's a crudely illustrated structure for this widget
As you can see "info text" is next to "video duration", but I want it at the top, and I want to keep "video duration" at the bottom at all times.
I tried using alignment settings but I don't know why one doesn't seem to be working (I commented it in the code below)
class MiniVideoCell extends StatelessWidget {
final lesson;
MiniVideoCell(this.lesson);
#override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
new Container(
padding: new EdgeInsets.all(12.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Column(
children: <Widget>[
new Image.network(
lesson.imageUrl,
width: 150.0,
),
],
),
new Column(
crossAxisAlignment: CrossAxisAlignment.start, //meant to align elements to the left - seems to be working
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.start, //trying to bring this text up, not working
children: <Widget>[
new Text("info text"),
],
),
new Row(
children: <Widget>[
new Text("video duration"),
],
),
],
),
],
),
),
new Divider(),
],
);
}
}
You can try to set your mainAxisAlignment property of your Column widget to MainAxisAlignment.spaceBetween. This would put all available space between your Row widgets.
new Column(
crossAxisAlignment: CrossAxisAlignment.start, //meant to align elements to the left - seems to be working
mainAxisAlignment: MainAxisAlignment.spaceBetween, // Add this line
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.start, //trying to bring this text up, not working
children: <Widget>[
new Text("info text"),
],
),
new Row(
children: <Widget>[
new Text("video duration"),
],
),
],
)
And also we need to specify the height and width of our Container widget like this:
Container(
padding: EdgeInsets.all(12.0),
width: double.infinity, // Added width
height: 124.0, // Set your preferred height
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
...
Output would look like this:
Here is the partial code:
Column(
children: [
Container(
padding: EdgeInsets.all(12.0),
width: double.infinity, // Added this
height: 124.0, // Set your preferred height
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Column(
children:[
Container(
color: Colors.blue,
width: 150.0,
height: 100.0, // Assuming that the height of the thumbnail is 100 pixels
)
]
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween, // Place all available space between the children
children:[
Row(
mainAxisAlignment: MainAxisAlignment.start, //trying to bring this text up, not working
children: <Widget>[
new Text("info text"),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start, //trying to bring this text up, not working
children: <Widget>[
new Text("video duration"),
],
),
]
)
]
),
),
Divider(),
I'm trying to show a text in multiple lines, I mean like this:
"I am a text
and I finish here"
When I try to do that, I see a bar that says "Right Overflowed by 443 pixels".
I have this UI structure:
#override
Widget build(BuildContext context) {
return Card(
child: Scaffold(
body: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(15.0),
child: Image.asset('images/place.png'),
)
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 15.0),
child: Text(
_placeCard.description,
style: TextStyle(),
softWrap: true
)
)
],
),
],
),
)
);
}
Where _placeCard.description is something like : "nce thethethe the the the 1500s, when an unknown printer took a galley of type and scrambled it to"
Could someone help me or give me any feedback?
Wrap your Text widget using a Flexible widget.
like,
//updated read: aziza comment
Flexible(//newly added
child: Container(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 15.0),
child: Text(
_placeCard.description,
style: TextStyle(),
softWrap: true
),
)
)
A simple example in below link:
https://gist.github.com/Blasanka/264510a0e7e5aaa151f02ada19fd466d
Update:
Above solution wraps the Text widget but in your question code snippet, the problem is you are using two Columns inside a Row and you havent added constraint. So, the easy solution to wrap those two Column widget using Flexible widgets.
like below,
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: Column(
//...
),
),
Flexible(
child: Column(
//...
),
),
],
),
Try wrapping your text widget in Expanded class and set it's flex factor. It will force the text to fit within the container.
Card(
color: kBoxColor,
child: Row(
children: [
Icon(Icons.description),
SizedBox(width:20.0),
Expanded(
flex: 30,
child: Text(
// Extremely long text,
style: kAnsTextStyle,
),
),
],
),
),
I am a complete newbie in Flutter, but I already like it.
The question is:
why is the column not expanding to the full height?
code is on gist.github
Using CrossAxisAlignment.stretch works for me:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text("Some title"),
Text("Address"),
Text("Description")
],
),
A Column widget is flexible - it will try to take up as much space as it needs but no more. If you want it to take up all availible space, then wrap it in an Expanded widget.
createChildren() {
return [
Image.network(
testImg,
height: imageSize,
width: imageSize,
),
Padding(padding: EdgeInsets.only(left: 16.0)),
Expanded(child:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
boldText("Some title"),
Text("Address"),
Text("Description")
],
),
),
];
}
Wrapping the column with a row with MainAxisSize.max
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Column(
children: <Widget>[
_someWidget(),
_someWidget(),
_someWidget(),
],
),
],
)
Don't use flex=1 inside Column, here you can see example
children: [
MyWidget(),
Expanded(
child: MyWidget(),
),
MyWidget(),
],
Based on your layout I assume that your Column is nested inside a Row. Wrap your Row with IntrinsicHeight and your Column will automatically expand its height to be the same as the Row's tallest child:
IntrinsicHeight(
child: Row(
children: [
Container(width: 40, height: 40, color: Colors.blue),
// tallest child
Container(width: 40, height: 60, color: Colors.blue),
// height will be 60
Column(
...
),
],
),
)
You can wrap the Column inside an infinite width SizedBox.
SizedBox(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [ ... ]
)
)
The above code snippet will place the children at the center of the SizedBox. It'll work especially well if you want to use a Column as the body of your Scaffold. In that case children will show up at the center of the screen.
The code linked in the question is no longer available, so I can't give you a full working example for your case. However, one thing that will likely work is using mainAxisAlignment as follows:
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
Text("Some title"),
Text("Address"),
Text("Description")
],
),
(mainAxisSize: MainAxisSize.max is actually the default value, butthis only works if you do not set it to MainAxisSize.min, so I included it here.)
Setting mainAxisAlignment to MainAxisAlignment.spaceAround or MainAxisAlignment.spaceEvenly will also expand the column, but spacing between/around children will be handled differently. Try it out and see which you like best!
This will cause the column to take all the space it can - if it still doesn't expand then that is due to its parent widget, and we can no longer access the code so I can't speak to that.