skills/flutter/references/core-layout.md

5.4 KiB

name description
core-layout Flutter layout system - constraints, Row, Column, Stack, Flex, and sizing widgets

Layout System

Flutter's layout system uses a constraint-based approach where parent widgets provide constraints to their children, and children determine their size within those constraints.

Layout Constraints

Flutter uses BoxConstraints to define the size constraints for widgets:

  • minWidth, maxWidth - Horizontal constraints
  • minHeight, maxHeight - Vertical constraints
  • isTight - Constraints are exactly specified (min == max)
  • isLoose - Constraints allow flexibility (min < max)
// Tight constraints - widget must be exactly 100x100
Container(
  width: 100,
  height: 100,
  child: child,
)

// Loose constraints - widget can be any size up to 200x200
ConstrainedBox(
  constraints: const BoxConstraints(
    maxWidth: 200,
    maxHeight: 200,
  ),
  child: child,
)

Flex Layouts (Row & Column)

Row and Column arrange children in a single direction. They use the Flex layout algorithm.

Row

Row(
  mainAxisAlignment: MainAxisAlignment.start, // start, end, center, spaceBetween, spaceAround, spaceEvenly
  crossAxisAlignment: CrossAxisAlignment.center, // start, end, center, stretch, baseline
  mainAxisSize: MainAxisSize.max, // max, min
  textDirection: TextDirection.ltr,
  verticalDirection: VerticalDirection.down,
  children: [
    Container(width: 50, height: 50, color: Colors.red),
    Container(width: 50, height: 50, color: Colors.green),
    Container(width: 50, height: 50, color: Colors.blue),
  ],
)

Column

Column(
  mainAxisAlignment: MainAxisAlignment.start,
  crossAxisAlignment: CrossAxisAlignment.center,
  mainAxisSize: MainAxisSize.max,
  children: [
    Container(width: 50, height: 50, color: Colors.red),
    Container(width: 50, height: 50, color: Colors.green),
    Container(width: 50, height: 50, color: Colors.blue),
  ],
)

Flexible & Expanded

Use Flexible and Expanded to control how children fill available space in Row/Column.

Row(
  children: [
    Expanded(
      flex: 2, // Takes 2/3 of available space
      child: Container(color: Colors.red),
    ),
    Expanded(
      flex: 1, // Takes 1/3 of available space
      child: Container(color: Colors.green),
    ),
  ],
)

Row(
  children: [
    Flexible(
      flex: 1,
      fit: FlexFit.loose, // Can be smaller than available space
      child: Container(color: Colors.red),
    ),
    Expanded(
      flex: 1,
      child: Container(color: Colors.green), // Must fill available space
    ),
  ],
)

Stack Layout

Stack allows widgets to be positioned on top of each other.

Stack(
  alignment: Alignment.center, // How to align non-positioned children
  fit: StackFit.loose, // loose, expand, passthrough
  clipBehavior: Clip.hardEdge, // none, hardEdge, antiAlias, antiAliasWithSaveLayer
  children: [
    Container(width: 200, height: 200, color: Colors.blue),
    Positioned(
      top: 10,
      left: 10,
      child: Container(width: 50, height: 50, color: Colors.red),
    ),
    Positioned(
      bottom: 10,
      right: 10,
      child: Container(width: 50, height: 50, color: Colors.green),
    ),
  ],
)

Container

Container combines common painting, positioning, and sizing widgets.

Container(
  width: 100,
  height: 100,
  padding: const EdgeInsets.all(16),
  margin: const EdgeInsets.all(8),
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(8),
    border: Border.all(color: Colors.black, width: 2),
    boxShadow: [
      BoxShadow(
        color: Colors.black.withOpacity(0.2),
        blurRadius: 4,
        offset: const Offset(0, 2),
      ),
    ],
  ),
  child: const Text('Hello'),
)

Sizing Widgets

SizedBox

Fixed size box.

SizedBox(
  width: 100,
  height: 100,
  child: child,
)

ConstrainedBox

Apply constraints to a child.

ConstrainedBox(
  constraints: const BoxConstraints(
    minWidth: 100,
    maxWidth: 200,
    minHeight: 50,
    maxHeight: 100,
  ),
  child: child,
)

UnconstrainedBox

Remove constraints from parent (use with caution).

UnconstrainedBox(
  constrainedAxis: Axis.horizontal,
  child: child,
)

AspectRatio

Enforce a specific aspect ratio.

AspectRatio(
  aspectRatio: 16 / 9,
  child: Container(color: Colors.blue),
)

FittedBox

Scale and position a child to fit within available space.

FittedBox(
  fit: BoxFit.contain, // contain, cover, fill, fitWidth, fitHeight, none, scaleDown
  alignment: Alignment.center,
  child: child,
)

LayoutBuilder

Use LayoutBuilder to build widgets based on available constraints.

LayoutBuilder(
  builder: (context, constraints) {
    if (constraints.maxWidth > 600) {
      return WideLayout();
    } else {
      return NarrowLayout();
    }
  },
)

Key Points

  • Flutter uses a constraint-based layout system
  • Parent widgets provide constraints, children determine their size
  • Row and Column use the Flex layout algorithm
  • Stack allows overlapping widgets
  • Use Expanded/Flexible to control space distribution in Row/Column
  • Container combines multiple layout and styling widgets
  • Use LayoutBuilder to build responsive layouts based on constraints