Flutter Container inside a Container and Text widget - flutter

Container(
color: Colors.green,
width: 300,
height: 300,
child: Container(
color: Colors.purple,
width: 200,
height: 200,
),
),
when I do this why the child container size is the same as parent container size? but when i pass alignment: Alignment.center inside the parent container, this give a expected output?
Output

Because the parent widget forces the child widget to be the same exact size.
From the docs:
If a child wants a different size from its parent and the parent
doesn’t have enough information to align it, then the child’s size
might be ignored. Be specific when defining alignment.
You could also wrap the inner Container in a Center widget and it would also work.
See the examples here https://docs.flutter.dev/development/ui/layout/constraints

Related

Why does a SizedBox in another SizedBox ignore its width and hight?

When I nest two SizedBoxes, the width and height of the inner box are ignored. Why is this, how can I work around it?
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: SizedBox(
width: 300,
height: 500,
child: SizedBox(
width: 200, height: 200, child: Container(color: Colors.green)),
));
}
}
In this example, I have a 300x500 sized box and an inner 200x200 SizedBox. In the picture you can see that the green box is the size of the outer SizedBox but should actually be a 200x200 square.
According to flutter documentation: If given a child, this widget forces it to have a specific width and/or height. These values will be ignored if this widget's parent does not permit them. For example, this happens if the parent is the screen (forces the child to be the same size as the parent), or another SizedBox (forces its child to have a specific width and/or height). This can be remedied by wrapping the child SizedBox in a widget that does permit it to be any size up to the size of the parent, such as Center or Align.
So wrapping the child with center would solve the problem:
Center(
child: SizedBox(
width: 300,
height: 500,
child: Center(
child: SizedBox(
width: 200, height: 200, child: Container(color: Colors.green)),
),
)),
The problem is, SizedBox can set widget size only within the constrains set by the parent. Many widgets, like Padding, want their child to occupy 100% of the space available to them. This makes sense, because if the child is smaller they wouldn't know where to put it.
If you want the child to be smaller than the parent you could use Center or Align, e.g. replace
I had the same issue and I solved my problem using the FractionallySizedBox class.
You can specify the suitable size using fractions of the above SizedBox as widthFactor and heightFactor:
Widget build(BuildContext context) {
return SizedBox.expand(
child: FractionallySizedBox(
widthFactor: 0.5,
heightFactor: 0.5,
alignment: FractionalOffset.center,
child: DecoratedBox(
decoration: BoxDecoration(
border: Border.all(
color: Colors.blue,
width: 4),
),
),
),
);
}

Incoming constraints for Container in Flutter. Do i get it wrong?

As documentation says
Containers with no children try to be as big as possible unless the
incoming constraints are unbounded, in which case they try to be as
small as possible
Well when I make incoming constraints unbounded for inner Container i suppose that it should be as small as possible but it expands for entire screen.
body: Container(
color: Colors.red,
constraints: const BoxConstraints(
maxHeight: double.infinity,
maxWidth: double.infinity,
),
child: Container(
color: Colors.green,
),
),
Why?
If you read the documentation a bit further, you'll see that constraint arguments on the Container itself will override this behavior:
Containers with no children try to be as big as possible unless the incoming constraints are unbounded, in which case they try to be as small as possible. Containers with children size themselves to their children. The width, height, and constraints arguments to the constructor override this.
Try wrapping the inner childless Container in an UnconstrainedBox, and you'll see it will shrink to zero width and height.
body:
Container(
color: Colors.red,
width: double.infinity,
height:double.infinity,
child: UnconstrainedBox(
child: Container(
color: Colors.green,
),
),
)
Although red container has infinite size, You put it in a scaffold's body which has specific size. so your red container get specific size then your grin container with no child get size as much as its parents.
The red container actually will has size as small as posibble depends its child.
the green container has no child, then as the documentation said it will try to be as big as possible unless the incoming constraints are unbounded,
if you change the child , like Text widget, or Column, or other widget, it will not get the maximum size.

Flutter: child button filling container size with explicit size

I'm trying to have a button nested in a container with a specific background color. I'm setting the height on the Container and on the MaterialButton nested within. I would expect the MaterialButton to maintain it's height of 40, while in the container of height 100. Instead, the MaterialButton is stretch to the height and width of the container.
Container(
color: lightBackground,
height: 100,
width: double.infinity,
child: MaterialButton(
height: 40,
child: Text('Hi'),
color: primaryColor,
onPressed: () {},
))
Anyone know how to get round this? Thanks.
The simple solution is to set alignment: Alignment.center for the Container, or wrap the Button with a Center widget.
For example:
Container(
height: 100,
alignment: Alignment.center,
child: ...
)
The long explanation has to do with Flutter Layout Constraints. You can read more about it at the official doc here.

Flutter Container not wrapping to size of container when alignment property is used

I have a container A and a container B such that container A contains container B.
I expect the the container A to wrap itself to the size of the child ie. container B as a container is defined in Flutter doc.
It works as expected and the container A size wraps just to fit the Container B. Very well
However, when alignment property is used on the container A, the Container A extends full height without honouring the height of the container B.
Here is my code :
Container(
alignment: Alignment.bottomLeft,
child : Container(child: SizedBox(width:30, height: 300,), color: Colors.green,),
width: 60,
color: Colors.blue,
)
How can I use alignment property of the container expecting normal behaviour?
According to chat conversation this is the required outcome
Container(
color: Colors.red,
child: Row(
children: <Widget>[
Container(
height: 300,
width: 30,
color: Colors.green,
)
],
),
)
I have a second question on this regard..if you can answer. What if i
reverse my case and would want to have my child align to right and
have a breather space to its left?
Add mainAxisAlignment: MainAxisAlignment.end inside your row

Flutter SizedBox vs LimitedBox

I have read docs for both SizedBox and LimitedBox, and didn't find any practical difference between the two.
Can anyone give an example when one may fail and other work?
So what I have found is, LimitedBox is only usable when the child is given unconstrained width/height by its parent.
And SizedBox simply creates a box with given width/height and doesn't allow child to go beyond given dimensions.
Example: (LimitedBox)
#override
Widget build(BuildContext context) {
return Scaffold(
body: LimitedBox(
maxHeight: 50, // no impact because it's child `Text` width/height isn't unconstrained
child: Text(
"A",
style: TextStyle(fontSize: 200),
),
),
);
}
Example (SizedBox)
#override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
height: 50, // has impact, it won't let Text to be of more than 50 logical pixels high
child: Text(
"A",
style: TextStyle(fontSize: 200),
),
),
);
}
Note: If anyone has better answer, I am happy to accept theirs.
LimitedBox is a SizedBox unless the parent widget imposes a constraint.
From Doc
A box that limits its size only when it's unconstrained.
Reference
Flutter doc
LimitBox:
LimitBox works only when it's size is unconstrained If this widget's
maximum width is unconstrained then its child's width is limited to
[maxWidth]. Similarly, if this widget's maximum height is
unconstrained then its child's height is limited to [maxHeight].
Example:
Center(
child: LimitedBox(
maxWidth: 50,
child: Container(
color: Colors.red,
width: 20,
height: 100,
)
),
),
Output:
This restricts Container Widget with a max-width as 50 but it's going to show widget till container width which is 20.
SizeBox:
It comes with fixed sizes that restrict its child to render on the
limited area. If either the width or height is null, this widget will
try to size itself to match the child's size in that dimension. If the
child's size depends on the size of its parent, the height and width
must be provided.
Example:
Center(
child: SizedBox(
width: 50,
child: Container(
color: Colors.red,
width: 20,
height: 100,
)
),
),
Output:
This will also behave like LimitedBox but the only difference here Container will be rendered till width 50 of SizeBox, it will not consider it's own width which is 20 and drawn till the parent widget.
Can anyone give an example when one may fail and other work?
They'll both work, but they'll do different things. The example from the LimitedBox documentation says:
This is useful when composing widgets that normally try to match their parents' size, so that they behave reasonably in lists.
Imagine that you are creating a reusable widget and don't have control over where it's used. You could use a SizedBox, but then your widget will always have the specified size, even if its size is already constrained by a parent widget.