Reputation: 1112
I'm practicing with flutter Container these days, and this example I came up with is simply astonishing
I put a Container of size 50x50 inside a Container of size 200x200. Strange is that the inner Container expand to 200x200 even though it has a tight constraint of 50x50.
Here's the code
Container(
width: 200.0,
height: 200.0,
color: Colors.orange,
child: Container(
width: 50.0,
height: 50.0,
color: Colors.blue,
),
)
I expect a small blue box inside a bigger orange box.
Could someone explain why?
Upvotes: 45
Views: 23543
Reputation: 630
If you want to draw 50 * 50
container inside 200 * 200
container, @Richard Heap answers properly. I try to explain the behaviour internally.
Container(
width: 50.0,
height: 50.0,
color: Colors.blue,
)
How does this translates, Container
is just wrapper of several low level widgets, since it's mentioned color
, this will translate to ColoredBox
, since it's mentioned width
and height
it'll use to build tight constraints using ConstrainedBox
widget. Since ColoredBox
is required, it'll wrap with child to get finally
ContrainedBox(constraints: <height, width tight>, child: ColoredBox(...))
With similar logic, with Outside container,
Container(
width: 200.0,
height: 200.0,
color: Colors.orange,
child: Container(
width: 50.0,
height: 50.0,
color: Colors.blue,
),
)
it'll be translated to
ConstrainedBox(
constraints: <heigh=200, width=200 tight>,
child: ColoredBox(color: Colors.orange,
child: ConstrainedBox(
constraints: <height=50, width=50 tight>,
child: ColoredBox(color: Colors.blue)
)
)
)
Note that we're passing tight constraints here, means minHeight
= maxHeight
= height
. Similarly minWidth
= maxWidth
= width
. Top level ConstrainedBox
dictates the all children to be only 200 * 200
- non negotiable.
So top-level ConstrainedBox
, asks the Orange ColoredBox
to be 200 * 200
(due to tight constraints, it sets minWidth
= 200, maxWidth
= 200, minHeight
= 200, and maxHeight
= 200 ), so it draws orange color of 200 * 200
. And Orange ColoredBox
pass the 200 * 200
tight constraints to inner ConstrainedBox
, since it has it's own constraints, it'll apply clamping, during clamping it needs to honour the min, max height/width given by the parent, so it'll use following formula to calculate
minHeight = 50.clamp(200, 200) // result will be 200 for all
maxHeight = 50.clamp(200, 200)
minWidth = 50.clamp(200, 200)
maxWidth = 50.clamp(200, 200)
So the height and width will 200 each. It draws Blue ColoredBox
with 200 * 200
on top of Orange ColoredBox
.
Container(
width: 200.0,
height: 200.0,
color: Colors.orange,
alignment: Alignment.center, // where to position the child
child: Container(
width: 50.0,
height: 50.0,
color: Colors.blue,
),
),
The alignment option makes Container to wrap the child with Align
widget. so the final translated widget tree is...
ConstrainedBox(
constraints: <heigh=200, width=200 tight>,
child: ColoredBox(color: Colors.orange,
child: Align(
child: ConstrainedBox(
constraints: <height=50, width=50 tight>,
child: ColoredBox(color: Colors.blue)
)
)
)
)
So Align
widget need to be 200 * 200
due to constraints passed from the parent - Orange ColoredBox
. However, 'Align' won't pass same constraints to the child. So the inner ConstrainedBox
will have 50 * 50
constraints on Blue ColoredBox
.
Here, Align
works as constraints
passage gate, it can modify the constraints, up to some limits, since it can position the child relatively wherever it wants, while ConstrainedBox
can't position it's children wherever they want, they need pass the constraints to children as they are.
Upvotes: 0
Reputation: 21
In the code below we created a container that has a child called text and tried to style them a bit to make them look better.
Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.circular(15)
),
padding: const EdgeInsets.all(10),
margin: const EdgeInsets.all(10),
child: const Text('orange juice is very delicious',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 22,
fontWeight: FontWeight.bold
),
),
),
Upvotes: 0
Reputation: 51750
You need to specify where in the orange box you would like the blue box displayed, otherwise the blue box will grow to the size of its parent.
Container(
width: 200.0,
height: 200.0,
color: Colors.orange,
alignment: Alignment.center, // where to position the child
child: Container(
width: 50.0,
height: 50.0,
color: Colors.blue,
),
),
Upvotes: 110