Column child Container covers full width of parent - flutter

I am adding a Container inside Column. I have given Container fixed width 60% of device width and height is 30% of device height. For height it is reflecting good but width covering whole parent.
I am not sure what I am doing wrong.
Here is my code:
Scaffold(
body: Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height*.30,
child: Container(
width: MediaQuery.of(context).size.width*.20,
height: 40,
child: Text('test'),
color: Colors.blueAccent,
),
),
Expanded(
child: ListView(
children: chatList.map((chatModel) {
return ChatTileWidget(chatModel: chatModel,);
}).toList(),
),
)
],
),
);

Constraints in Flutter works different than usual. If you want to give height and width to the child, it will usually follows its parents constraints.
To read more about Constraints in Flutter: Understanding Constraints.
To get what you want, you need to use Align and set the alignment property to your preferred position. Here is an example for you. I have wrapped your inner Container with an Align widget and set the alignment to topLeft so it doesn't take it's parent height and width:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.3,
child: Align(
alignment: Alignment.topLeft,
child: Container(
height: 40.0,
color: Colors.blueAccent,
width: MediaQuery.of(context).size.width * 0.2,
child: Text('test')
)
)
)
]
)
RESULT
To know more about Align, please see this: Align Class.

Related

How to make flutter tabbar view hight is flexible based on child hight?

I have a flutter widget tree as the following:
Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
Container(
height: 750),
),
DefaultTabController(
length: 5,
child: Column(
children: [
SizedBox(
height: 40,
width: double.infinity,
child: TabBar(
),
Container(
height: 750
child: TabBarView(children: [
BusinessProfileOverviewPage(),
BusinessProfileGalleryPage(),
BusinessProfilePageReviews(),
BusinessProfileOffersPage(),
BusinessProfilesProductsPage(),
]),
),
],
),
),
]))
I want to get rid off the tabbarview container height, so it becomes felxible based on the contents of the child pages.
when I remove the fixed height I get error of unbounded heights.
I tried also box constrains, but childs always tak the max height.
how can I adjust that?
thanks

How can I achieve the following layout in flutter?

The thing I want to reach is something like this:
These are the main constraints I want to reach:
"text"-s being centered above the lower "button"-s and "thing2" being able to go in between "texts"-s when the screen is short enough.
I want the "button"-s to always be the same height/width (this is easily done by something like SizedBox) and the same distance from the top/bottom .
I want the "thing1" to be x height at max and scale with screen downwards if needed (either by making its texts smaller or making it scrollable, I haven't yet decided, this isn't the main problem).
I want "thing2" to always scale with screen.
When the screen is big enough, I want "thing1" and "thing2" to share the space between them evenly, and each being in the center of its own space.
Right now my layout is the following:
Column: MainAxisAlignment.SpaceBetween, height fixed
Container: height fixed
Row: MainAxisAlignment.SpaceBetween
Button
Button
Container: height fixed
thing1
Container: height calculated based on screen height and other Containers' height
thing2
Container: height fixed
Row: MainAxisAlignment.SpaceBetween
Button
Button
This is of course not all, I tried to include all relevant information about my layout without giving too much information pointlessly.
How would one go about adding the "text"-s above the "button"-s? (I tried Stack, but then I dont't know how to make them appear above the "button"-s while at the same time making "thing2" be above them too.
I managed achieve the things with this code (where MyBox is a simple widget with a colored container with width and height):
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
const double buttonHeight = 35;
const double buttonWidth = 100;
const double textHeight = 40;
const double textWidth = 30;
return Padding(
padding: const EdgeInsets.all(8.0),
child: Stack(
children: [
Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: buttonWidth,
height: buttonHeight,
child: MyBox(Colors.red),
),
),
Align(
alignment: Alignment.topRight,
child: SizedBox(
width: buttonWidth,
height: buttonHeight,
child: MyBox(Colors.yellow),
),
),
Align(
alignment: Alignment.bottomLeft,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: textWidth,
height: textHeight,
child: MyBox(Colors.green),
),
),
SizedBox(
width: buttonWidth,
height: buttonHeight,
child: MyBox(Colors.cyan),
),
],
),
),
Align(
alignment: Alignment.bottomRight,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: textWidth,
height: textHeight,
child: MyBox(Colors.indigo),
),
),
SizedBox(
width: buttonWidth,
height: buttonHeight,
child: MyBox(Colors.blue),
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: buttonWidth,
height: buttonHeight,
child: MyBox(Colors.orange),
),
),
Positioned(
left: 0,
top: 0,
right: 0,
bottom: buttonHeight,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
fit: FlexFit.loose,
child: MyBox(Colors.purple),
),
Flexible(
fit: FlexFit.loose,
child: MyBox(Colors.brown),
),
],
),
),
],
),
);
}
}
TLDR: I used a Stack widget to hold my other widgets, and Align widget to align (duh) my widgets in the Stack.
I used a Column to center my texts above my lower buttons. "mainAxisAlignment: MainAxisAlignment.end" was important so this column is at the bottom and not at the topside.
Finally I wrapped the Stack in a Padding.

Grow a container while maintaining heights of the other containers in flutter

I have these three containers. That the first one needs to grow to cater for the children that will be in it. The second one could have a fixed height say a flex factor of 1, while the third one has a fixed height too say flex of 2. The whole of this screen can be scrollable. It actually has to be scrollable since the children of the first container can be a lot.
Note: the children of the first container will have a fixed height, the container will house a listview or column which will have fixed height children, say containers each of 50.0. How do I achieve this, especially the 'growability' of the first container, while maintaining the heights of the other containers.
What I have currently is
SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
child: ListView(
children: [
Flexible(
flex: 1,
child: Container(
color: Colors.blueAccent[200],
child: Column(children: [
Container(
height: 100.0,
color: Colors.greenAccent[200],
),
Container(
height: 100.0,
color: Colors.purpleAccent[200],
),
Container(
height: 100.0,
color: Colors.orangeAccent[200],
)
]),
)),
Expanded(
flex: 1,
child: Container(
color: Colors.redAccent[100],
),
),
Expanded(
flex: 1,
child: Container(
//height: 120.0,
color: Colors.redAccent[400],
),
),
],
),
),
),
Which just brings up lots and lots of errors, does not matter how I lay it out using flexibles and Expanded widgets. Again, I don't need the first container to scroll internally, it should grow according to the number of children in it, while the rest of the two containers maintain their heights.
You can not user Expanded or Flexible inside a scrollable widget since the child of Expanded will then get a height of infinity and the height of the child of Flexible will not get its parents height to compare with.
You can set the height of the bottom two containers based on the height of the screen.
SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
child: ListView(
children: [
Container(
color: Colors.blueAccent[200],
child: Column(
children: [
Container(
height: 100.0,
color: Colors.greenAccent[200],
),
Container(
height: 100.0,
color: Colors.purpleAccent[200],
),
Container(
height: 100.0,
color: Colors.orangeAccent[200],
)
],
),
),
Container(
// 33 % of the screen height
height: .33 * MediaQuery.of(context).size.height,
color: Colors.redAccent[100],
),
Container(
// 33 % of the screen height
height: .33 * MediaQuery.of(context).size.height,
color: Colors.redAccent[400],
),
],
),
),
),

How can I stretch a container vertically to max screen?

body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
width: 100.00,
height: 100.00,
color: Colors.red,
),
])),
));
Currently, the height is 100.00, but I need to stretch it to infinity.
I tried to change the height to double.infinity:
Container(
width: 100.00,
height: double.infinity,
color: Colors.red,
But then I receive the following error:
The following assertion was thrown during performLayout():
BoxConstraints forces an infinite height.
To achieve this, you can either:
1) Use a widget called Expanded widget.
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
color: Colors.red,
),
),
])),
));
2) Give the Container a height and width of the device screen using the MediaQuery class
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
// give it a width equals to the device screen
width: MediaQuery.of(context).size.width,
// give it a height equals to the device screen
height: MediaQuery.of(context).size.height,
color: Colors.red,
),
])),
));
Wrap your Container with an Expanded-Widget and remove the height completely.
Expanded(
child: Container(
width: 100.00,
color: Colors.red,
),
),
The Expanded-Widget fills the available space of the child of a Row or a Column along the main-axis.
The right way to assign height to is the calculating height of
App Bar
Top Bar Space(Exist on the above App Bar)
Remaining screen
Logic:
1. Get the MediaQuer
final mediaQuery = MediaQuery.of(context);
2. Declare the AppBar Widget and same App Bar instance should be used in Scaffold App Bar
final PreferredSizeWidget appBar = AppBar(
title: Text('Home'),
);
3. Use calculated height
Container(
width: mediaQuery.size.width,
height: (mediaQuery.size.height -
appBar.preferredSize.height -
mediaQuery.padding.top),
color: Colors.red,
),

ListView don't grow in cross axis

A regular vertical ListView would fill all the space on both axes, and shrinkWrap would make it shrink on the main axis, however, how can I make it shrink on the cross axis, just taking as much space as its biggest child needs, while being constrained by the maximum available horizontal space? Something like this:
You can't.
Children are laid out only when they are visible on screen. Which means ListView don't know the maximum cross-axis size of it's children.
If you have a small amount of children you can instead replace ListView by SingleChildSrollView and then add as a child a Column containing all your children
SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
color: Colors.red,
width: 50.0,
height: 200.0,
),
Container(
color: Colors.yellow,
width: 100.0,
height: 200.0,
),
Container(
color: Colors.red,
width: 50.0,
height: 200.0,
),
Container(
color: Colors.red,
width: 50.0,
height: 200.0,
),
],
),
),