Flutter Container's BoxConstrains not working as expected - flutter

this is the code
return MaterialApp(
home: Container(
constraints: BoxConstraints.tight(Size(100, 100)),
decoration: BoxDecoration(color: Colors.yellow),
child: Card(child: Text('Hello World')),
),
);
what i expected is Card is 100 x 100, but it's not, it just stretched to the whole screen. why does it happened?

The Flutter team released a great article named "Understanding constraints" that's definitely worth checking out if you're unsure about how constraints work.
That being said, here's a more in-depth answer specifically about your problem:
Why do your BoxConstraints get ignored?
The Container internally creates a ConstrainedBox in order to enforce your constraints.
The ConstrainedBox's RenderObject - a RenderConstrainedBox - then tries to adhere to your constraints as much as possible.
During layout, the following code taken from the RenderConstrainedBox implementation is executed.
The members minWidth, maxWidth, minHeight and maxHeight stem from your given constraints, while constraints are the constraints provided by the Flutter framework (in your case, the screen size).
BoxConstraints(
minWidth: minWidth.clamp(constraints.minWidth, constraints.maxWidth),
maxWidth: maxWidth.clamp(constraints.minWidth, constraints.maxWidth),
minHeight: minHeight.clamp(constraints.minHeight, constraints.maxHeight),
maxHeight: maxHeight.clamp(constraints.minHeight, constraints.maxHeight)
)
Because the screen size is inflexible, the constraints are tight, meaning constraints.minWidth == constraints.maxWidth and constraints.minHeight == constraints.maxHeight.
That forces clamp to ignore your constraints (for example, 2.clamp(3,3) == 3).
So there you have it:
The constraints you give to a Container will only be respected as much as possible.
Because the whole screen needs to be filled, the Container is forced to take the tight screen constraints, thereby ignoring your constraints.
What to do about it
To make it possible for the Container to respect your constraints, you have to give it more "breathing room", i.e. don't force it to fill the screen.
A simple solution would be to wrap it in a Center, but it depends on your preferences on where the Container should be aligned.

Related

Is flutter render infinity size?

I am new in flutter I can't understand that is infinity size render in flutter
If I use container with infinity width then it will render but in box constraints documentation infinity size can't render
This is because there is something constraining the widget, when you set as an example:
Container(
width: double.infinity,
),
it will try to take an infinity size, which usually will throw an error to you, but it's constrained so it takes the max possible width.
The Container widget is built on top of different multiples widgets such as ConstrainedBox, DecoratedBox, Align, LimitedBox... , the ConstrainedBox defaults to the BoxConstraints.expand(), check it's source code:
// ...
child: ConstrainedBox(constraints: const BoxConstraints.expand()),
);
but if you check also the Scaffold source code :
// ....
final BoxConstraints fullWidthConstraints = looseConstraints.tighten(width: size.width);
so trying to expand that Container even within infinity, will expand it at maximum on the fullWidthConstraints which is, in this case, the screen's width.

Why does ListView ignore constraints

Why does a ListView completely ignore imposed constraints?
#override
Widget build(BuildContext context) {
return Padding(
child: Container(
constraints: BoxConstraints(maxWidth: 500),
child: ListView(
children: buildList(data),
),
),
);
}
The displayed ListView does not seem to be bothered at all with the maxWidth:500 of the parent container (same if replaced with a ConstrainedBox) and all elements (which are Rows) go full screen width.
Why?
The solution is to work with width of children instead, but still I'd much rather constrain the entire listView, and also if there's a constraint, shouldn't everything inside be forced not to exceed it?
EDIT: After hours of trying various things it finally works. Turns out the list view needed to a child of a Center, otherwise it would not pay any attention to SizedBoxes, ConstrainedBoxes, Containers etc. you'd put on it or its children and stretch full screen no matter what.
What are the parent widgets of the Padding(child: Container(... list view ))? I mean are you sure that a parent is not imposing its constraints on its children? Try do replace your ListView with Container(color: Colors.red, height: 100) and see if it respects the constraints. If it does not, there probably is a parent widget with infinite width constraint or something like that!
A solution can be wrap your Container with an UnconstrainedBox but I would recommend first checking my first point :D

MaxHeight causes widget to expand

I'm building an expansible card in flutter, which I wanto to animate. I want the parent Container to have a limited height while the card is collapsed, and to have whatever height is necessary for the child when it's expanded. I can reach this result using maxHeight: double.infinity:
Container(
alignment: Alignment.topCenter,
clipBehavior: Clip.hardEdge,
constraints: isExpanded
? BoxConstraints(maxHeight: double.infinity)
: BoxConstraints(maxHeight: 76),
decoration: BoxDecoration(),
child: widget.child,
),
)
But whatever maxHeight value I use other than double.infinity causes the parent to have that exact height, instead of just having the height needed by the child. I can't use double.infinity because that's not animatable. I've tried following this answer's tips, but whatever I wrap the child with, the parent always grows. I've tried changing the child, but even if I use maxHeight on the child itself, the parent always grows to the defined maxHeight.
Why does this happen? Shouldn't maxHeight only cause the parent to expand if needed? How come it works correctly with double.infinity, but doesn't with anything else?
Also, I have tried reaching this result with AnimatedSize, it sort of works. When it is expanding, it works perfectly, but when the child is collapsing, it collapses instantly, and the AnimatedSize's animation follows after.
Edit:
I see what you mean, you want to use AnimatedContainer, but in order to be animated like you want it, it requires you to specify the height. double.infinity won't do in this case, the error message you're getting is correct.
There are ways to get widget height.. I suggest you check this answer: https://stackoverflow.com/a/49650741/7248289
Also, this one might help: https://stackoverflow.com/a/54173729/7248289

What is the difference between using ConstrainedBox and Container widgets to give constraints to their child box?

I found that the only difference between the Container() and ConstrainedBox() widgets (if we want to constrain its child), is the more properties in the Container() widget to customize its child, but are there any other differences? and are there any performance differences and when it is efficient to use what?
Container does not do anything by itself. It is only a utility widget that delegates functionality to other widgets. This means that the contraints argument of a Container is strictly equivalent to ConstrainedBox.
If you take a look at the source code for Container, you will find the following:
if (constraints != null)
current = ConstrainedBox(constraints: constraints, child: current);
→ there is no difference.
Container(
constraints: constraints,
child: child,
)
// does strictly the same as
ConstrainedBox(
constraints: constraints,
child: child,
)

Flutter - How to create fluid / dynamic container that follows it's parent height?

I want to have a line that has 100% parent height, the line should has a fluid height following it's parent's height. the parent's height would be dynamic because every content has it's own height. Just like in Path app.
This is my app, currently I'm setting the height as a constant, how to make it dynamic following it's parent's height? :
Container(
width: 1,
color: Colors. redAccent,
height: 300, // <-- this height
)
try to use the Expanded Widget which uses the available space. you just have to definewhat is the available space here
Expanded(
child: Container(
color: Colors.amber,
width: 100,
),
),
here, if you dont put something on top of the expanded, it will take all the screen
and if not on the bottom, it will reach the bottom of the screen.
it takes the whole free space.
I solved this by adding container and add border left :)