Flex
is the base class for Row
and Column
. It implements the flex layout protocol in an axis-agnostic manner.
Row
is identical to Flex
with a default axis of Axis.horizontal
.
Column
is identical to Flex
with a default axis of Axis.vertical
.
Flexible
is the base class for Expanded
. It is a parent data widget that alters its child’s flex value. Its default fit is FlexFit.loose
, which causes its child to be laid out with loose constraints
Expanded
is identical to Flexible
with a default fit of FlexFit.tight
. Consequently, it passes tight constraints to its children, requiring them to fill all available space.
All flexible containers follow the same protocol.
Layout children without flex factors with unbounded main constraints and the incoming cross constraints (if stretching, cross constraints are tight).
Apportion remaining space among flex children using flex factors.
Main axis size = myFlex
* (freeSpace
/ totalFlex
)
Layout each child as above, with the resulting size as the main axis constraint. Use tight constraints for FlexFit.tight
; else, use loose.
The cross extent is the max of all child cross extents.
If using MainAxisSize.max
, the main extent is the incoming max constraint. Else, the main extent is the sum of all child extents in that dimension (subject to constraints).
Children are positioned according to MainAxisAlignment
and CrossAxisAlignment
.
In short, containers size to their child plus any padding; in so doing, they respect any additional constraints provided directly or via a width or height. Decorations may be painted over this entire region. Next, a margin is added around the resulting box and, if specified, a transformation applied to the entire container.
If there is no child and no explicit size, the container shrinks in unbounded environments and expands in bounded ones.
The container widget delegates to a number of sub-widgets based on its configuration. Each behavior is layered atop all previous layers (thus, child refers to the accumulation of widgets). If a width or height is provided, these are transformed into extra constraints.
If there is no child and no explicit size:
Shrink when the incoming constraints are unbounded (via LimitedBox
); else, expand (via ConstrainedBox
).
If there is an alignment:
Align the child within the parent (via Align
).
If there is padding or the decoration has padding...
Apply the total padding to the child (via Padding
).
If there is a decoration:
Wrap the child in the decoration (via DecoratedBox
).
If there is a foreground decoration:
Wrap the child in the foreground decoration (via DecoratedBox
, using DecorationPosition.foreground
).
If there are extra constraints:
Apply the extra constraints to the incoming constraints (via ConstrainedBox
).
If there is a margin...
Apply the margin to the child (via Padding
).
If there is a transform...
Transform the child accordingly (via Transform
).