Skip to main content

Scaffolding, Layout, and Composition in Flutter

In this session, you will learn how to build mobile layouts in Flutter: structuring screen scaffolding (Scaffold and SafeArea), distributing elements on screen (Column, Row, Expanded), applying visual styling (Container and Padding), and resolving layout overflows (RenderFlex overflow) using SingleChildScrollView.


1. Architectural Convention: Screen vs. Page

In Flutter, a well-structured screen clearly separates the outer frame from the inner content:

  • Screen (Route Screen): The navigation destination. It is the sole entity responsible for returning the Scaffold (with its AppBar, BottomNavigationBar, or FloatingActionButton).
  • Page (Inner Canvas): The visual content that lives inside the body of the Screen. It must never return a Scaffold, only layout widgets (SafeArea, Column, ListView, etc.).

Screen vs Page Architecture

Why avoid nested Scaffolds?

Nesting a Scaffold inside another triggers serious UI conflicts: notifications (SnackBar) are hidden or misplaced, duplicate app bars (AppBar) consume valuable screen real estate, and the virtual keyboard covers input fields because both Scaffold instances attempt to resize simultaneously (resizeToAvoidBottomInset).


2. Scaffolding and Hardware: Scaffold and SafeArea

Modern mobile devices feature notches, rounded corners, punch-hole front cameras, and system gesture bars. Scaffold and SafeArea guarantee that your user interface is never obstructed by these hardware obstacles:

  • Scaffold: Provides the canonical Material Design slots (appBar, body, floatingActionButton, bottomNavigationBar).
  • SafeArea: Automatically injects the necessary inner insets to protect content from the top status bar and the bottom gesture/home bar.

SafeArea Protection


3. Linear Layout: Row and Column

To position elements in a single direction, Flutter provides Row (horizontal) and Column (vertical). Each operates across two coordinate axes:

Row and Column Axes

Main and Cross Axis Visual Alignments:

Visual Alignments in Row and Column

4. Responsive Layout: Expanded and flex

Instead of hardcoding fixed widths or calculating manual percentages using MediaQuery, we use Expanded so that a child absorbs the remaining available space:

  • Flexible space: Combining fixed-width boxes (e.g. 70px) with Expanded allows the flexible widget to adapt automatically to any screen width.
  • Proportions with flex: When placing multiple Expanded widgets, the integer factor flex divides the space proportionally (e.g., flex: 1 and flex: 2 allocate 33.3% and 66.6% of the remaining space).

Expanded and flex Proportions


5. Boxes and Styling: Container vs. Padding

Padding is a lightweight, single-responsibility widget designed purely for inner spacing. Container is the swiss-army knife combining dimensions, margins, borders, and complex decorations:

Box Model and BoxDecoration Rule

The Golden Rule of BoxDecoration

When using decoration: BoxDecoration(...), the background color must be defined inside BoxDecoration. Supplying color directly to the Container while simultaneously specifying decoration causes a fatal runtime assertion error ('color == null || decoration == null').


6. Overflow Prevention: SingleChildScrollView

When the children of a Column demand more height than the physical screen can offer, Flutter displays the infamous yellow and black hazard stripes (RenderFlex overflowed).

RenderFlex Overflow and Scroll Solution


Self-Assessment Quiz

Cargando cuestionario...