class TestPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: EdgeInsets.all(10),
child: Container(
width: 300,
color: Colors.orangeAccent,
child: Column(
// mainAxisSize: MainAxisSize.min,
children: [
Text('Hi', style: TextStyle(fontSize: 50)),
],
),
),
),
),
);
}
}
I went through the container docs but could not figure out why it is happening. Can someone please explain as to why the column is taking full width of it's parent?
To better understand how Container
works here is the implementation for the widget which you can find in the flutter sources:
Container({
Key? key,
this.alignment,
this.padding,
this.color,
this.decoration,
this.foregroundDecoration,
double? width,
double? height,
BoxConstraints? constraints,
this.margin,
this.transform,
this.transformAlignment,
this.child,
this.clipBehavior = Clip.none,
}) : assert(margin == null || margin.isNonNegative),
assert(padding == null || padding.isNonNegative),
assert(decoration == null || decoration.debugAssertIsValid()),
assert(constraints == null || constraints.debugAssertIsValid()),
assert(clipBehavior != null),
assert(decoration != null || clipBehavior == Clip.none),
assert(color == null || decoration == null,
'Cannot provide both a color and a decoration\n'
'To provide both, use "decoration: BoxDecoration(color: color)".',
),
constraints =
(width != null || height != null)
? constraints?.tighten(width: width, height: height)
?? BoxConstraints.tightFor(width: width, height: height)
: constraints,
super(key: key);
The interesting part is with the constraints
property:
constraints =
(width != null || height != null)
? constraints?.tighten(width: width, height: height)
?? BoxConstraints.tightFor(width: width, height: height)
: constraints
As you can see if you give a value to the width
and/or height
properties it will apply a BoxConstraints
to its children forcing your child widget Column
to comply to this constraints.
alignment
property works ?If you look in the source code for the Container
widget you will find this in its build
method.
Widget build(BuildContext context) {
Widget? current = child;
// ...
if (alignment != null)
current = Align(alignment: alignment!, child: current);
// ...
}
It means that by providing a non-null alignment
property your child
widget will be wrapped inside an Align
widget. Now let's take a look at the Align
widget implementation, more precisely at its createRenderObject()
method:
@override
RenderPositionedBox createRenderObject(BuildContext context) {
return RenderPositionedBox(
alignment: alignment,
widthFactor: widthFactor,
heightFactor: heightFactor,
textDirection: Directionality.maybeOf(context),
);
}
So by providing an Align
widget it will create a RenderPositionedBox
let's take a look at its implementation too throught the method performLayout()
:
@override
void performLayout() {
final BoxConstraints constraints = this.constraints;
final bool shrinkWrapWidth = _widthFactor != null || constraints.maxWidth == double.infinity;
final bool shrinkWrapHeight = _heightFactor != null || constraints.maxHeight == double.infinity;
if (child != null) {
child!.layout(constraints.loosen(), parentUsesSize: true);
size = constraints.constrain(Size(
shrinkWrapWidth ? child!.size.width * (_widthFactor ?? 1.0) : double.infinity,
shrinkWrapHeight ? child!.size.height * (_heightFactor ?? 1.0) : double.infinity,
));
alignChild();
} else {
size = constraints.constrain(Size(
shrinkWrapWidth ? 0.0 : double.infinity,
shrinkWrapHeight ? 0.0 : double.infinity,
));
}
}
And there it is you have some BoxConstraints
applied to your child
based on the maxWidth
and maxHeight
of its parent.