I know I will get a lot of negative remarks for this question, but I'm getting really frustrated.
I tested my app on a new iPhone 11pro and I get now a lot of renderflex errors. You all know the error logs - and even google give you some advice like " Have you considered using a Flex or Expanded parent? "
Now, for Text Widgets that go over, I use Expanded. .. and that's great. That's super! I just wrap my Text in an Expanded and it "wraps" the text around so it fits within its container.
But what would be the equivalent of wrapping other widgets like rows or columns, or singlechildscrollviews?
I tried to wrap them in an expanded, and I get the same error message.
I'm fed up.
Here is an example of some code:
Container(
// width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.height,
//TODO: checkboxes
child: Center(
child: Column(
// mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(width: 200,height: 100,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
checkbox(sun, days[sun]),
checkbox(mon, days[mon]),
checkbox(tue, days[tue]),
checkbox(wed, days[wed]),
checkbox(thu, days[thu]),
checkbox(fri, days[fri]),
checkbox(sat, days[sat]),
],
),
),
],
),
)
),
Approach 1 : Use ListView
child: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
height: 100,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Text("Example"),
SizedBox(width: 10),
Text("Example"),
SizedBox(width: 10),
Text("Example"),
SizedBox(width: 10),
Text("Example"),
SizedBox(width: 10),
Text("Example"),
SizedBox(width: 10),
Text("Example"),
SizedBox(width: 10),
Text("Example"),
SizedBox(width: 10),
Text("Example"),
SizedBox(width: 10),
Text("Example"),
SizedBox(width: 10),
Text("Example"),
SizedBox(width: 10),
Text("Example"),
SizedBox(width: 10),
Text("Example"),
],
),
),
],
),
),
),
Approach 2 : You can use Wrap instead of ListView if you want show all items in that child.
Related
I'm having issues with the layout because of the long text, I've tried using Expanded / Flexible with the text that is causing the issue to fill the space it needs but it's overflowing. I know the question is asked hundred times, but I don't understand where is the mistake. I tried applying to both Expanded / Flexible to all of the Row/Columns individually and too all at the same time (mostly I was trying out layouts to try to fix it), and I still have the issue... I even tried to use the FittedBox with fit: BoxFit.(all of them).
Container(
alignment: Alignment.centerLeft,
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(Icons.directions_car),
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Text 1"),
SizedBox(
height: 4,
),
Text('TEXT 2'),
],
),
SizedBox(
width: 27,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('1 World Way, Los Angeles, CA 90045, USA',
textAlign: TextAlign.left,
),
SizedBox(
height: 4,
),
Text('FLIGHT 3231'),
],
),
],
),
],
),
],
),
);
By my understanding, and do correct me if I'm wrong, applying Expanded / Flexible, Flexible takes only the needed space, and Expanded takes all available space, respecting the flex factor. So most of the time I use the Flexible widget, but this time it is not working.
Thanks in advance for the help!
Try using Expanded widget with flex value set as per the expectation of UI filling.
Sample Code:
Center(
child: Container(
height: 80,
color: Colors.yellow,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.bus_alert),
),
Expanded(
flex: 1,
child: Container(
width: 1,
color: Colors.green,
child: Column(
children: [Text("Text 1"), Text("Text 1")],
),
)),
Expanded(
flex: 3,
child: Container(
color: Colors.blue,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text("1 World Way, Los Angeles, CA 90045, USA"),
Text("FLIGHT 3231"),
],
),
))
],
),
))
Note: There is a limitation for the text content using. We need to make sure to set the height according to the expected text length.
You can use Flexible or Expanded Widget You should try to below code :
Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.blue,
),
borderRadius: BorderRadius.circular(15.0),
),
margin: EdgeInsets.all(16.0),
child: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.directions_car),
SizedBox(
width: 10,
),
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Text 1"),
SizedBox(
height: 4,
),
Text('TEXT 2'),
],
),
),
SizedBox(
width: 27,
),
Flexible(
child: Container(
child: Column(
children: [
Text(
'1 World Way, Los Angeles, CA 90045, USA',
textAlign: TextAlign.left,
),
SizedBox(
height: 4,
),
Text(
'FLIGHT 3231',
textAlign: TextAlign.left,
),
],
),
),
),
],
),
],
),
),
),
Your screen like this :
wrap it by a container with fixed width and then use auto_sized_text. Or you can wrap your Text widget by FittedBox by fixed width. it would do the same approach. Feel free to add maxLine, minFontSize and maxFontSize' in auto_sized_text. Using ExpandedorFlexible` only affects the size of the container when your text length is lower than the given width, and It does not help you in this situation.
If the text is really long, then using Expanded will wrap the text according to the parent widget, thus leading to change in the font size. You might consider using ellipsis.
return Container(
width:300 //give a width of your choice
child: Text('Any long text',
overflow:TextOverflow.ellipsis,
),
);
My Row is composed of two Flexible and one of them is a Column I would like this column to take all the available vertical space like in my original design.
I tried to wrap the Column with an Expanded but it seems that I can't. I tried the property Flexible.tight of the flexible but it didn't work.
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
flex: 2,
child: SizedBox(
height: 130.0,
width: 130.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(35.0),
child: CachedNetworkImage(
imageUrl: fakeOffers[index].imageUrl,
fit: BoxFit.cover,
placeholder: (context, url) => MC_Shimmer(),
),
),
),
),
Flexible(
flex: 3,
fit: FlexFit.tight,
child: Container(
child: Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
fakeOffers[index].title,
style: MC_favoriteOfferTitle,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
Text(
fakeOffers[index].price.toStringAsFixed(0) + ' €',
style: MC_priceGradientDetail,
),
Text(
fakeOffers[index],
style: MC_favoriteOfferMeta,
),
],
),
),
),
)
],
);
You need to drop the first Flexible (it's fixed size anyway) and convert the second Flexible to an Expanded. This will let this Expanded take up all remaining space. Then, your column needs to take up all available space using CrossAxisAlignment.stretch.
So to solve the problem I just set the height of the column to 130.0 as I have a fixed size image.
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 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!
I'm trying to bottom-center a widget at the bottom of a Column, but it keeps aligning to the left.
return new Column(
new Stack(
new Positioned(
bottom: 0.0,
new Center(
new Container(),
),
),
),
);
The existence of the Positioned forces the Container to the left, instead of centering. Removing the Positioned, however, puts the Container in the middle-center.
Align is the way to go if you have only one child.
If you have more, consider doing something like this:
return new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
// Your elements here
],
);
The easiest and the correct way to do it - use Spacer()
Example:
Column(
children: [
SomeWidgetOnTheTop(),
Spacer(),
SomeCenterredBottomWidget(),
],
);
Expanded(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 10.0),
child: //Your widget here,
),
),
),
I have used this approach,
What i want is, A layout always in bottom but whenever Keyboard pops-up that layout also comes over it
body: Container(
color: Colors.amber,
height: double.maxFinite,
child: new Stack(
//alignment:new Alignment(x, y)
children: <Widget>[
new Positioned(
child: myWidget(context, data.iconName, Colors.red),
),
new Positioned(
child: new Align(
alignment: FractionalOffset.bottomCenter,
child: myWidget(context, data.iconName, Colors.green)
),
)
],
),
),
1) You can use an Align widget, with FractionalOffset.bottomCenter.
2) You can also set left: 0.0 and right: 0.0 in the Positioned.
Just expanding the answers:
Spacer is an option no one mentioned yet; it is used in case you prefer not to use Positioned / Align.
Align works if you want to specify the alignment of a child inside a parent. Use it anywhere but directly inside Stack
Positioned is similar to Align, but works only under Stack directly.
Design everything using Expanded() is one of the easiest way to do this
Column(
children: [
Expanded(
child: Placeholder(),
flex: 1,
),
Expanded(
child: Placeholder(),
flex: 10,
),
Expanded(
flex: 2,
child: Placeholder(),
)
],
),
If you wish to leave content as it, can wrap it with scrollable.
Useful if you have inputs in the children:
return Stack(
children: <Widget>[
Positioned(
child: SingleChildScrollView(
child: Column(
children: children
..add(Container(
height: 56, // button heigh, so could scroll underlapping area
)))),
),
Positioned(
child: Align(
alignment: Alignment.bottomCenter,
child: button,
),
)
],
);
Widget _bottom() {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Container(
color: Colors.amberAccent,
width: double.infinity,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<int>.generate(50, (index) => index + 1)
.map((item) {
return Text(
item.toString(),
style: TextStyle(fontSize: 20),
);
}).toList(),
),
),
),
),
Container(
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'BoTToM',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 33),
),
],
),
),
],
);
}
Wrap your Container in SingleChildScrollView() widget. Then it will not come above when keyboard pops up.
In addition of Stack:
to avoid floating container on keyboard, use this
return Scaffold(
appBar: getAppBar(title),
resizeToAvoidBottomInset: false,
body: