flutter-building-layouts
Original:🇺🇸 English
Translated
Builds Flutter layouts using the constraint system and layout widgets. Use when creating or refining the UI structure of a Flutter application.
106installs
Sourceflutter/skills
Added on
NPX Install
npx skill4agent add flutter/skills flutter-building-layoutsTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Architecting Flutter Layouts
Contents
- Core Layout Principles
- Structural Widgets
- Adaptive and Responsive Design
- Workflow: Implementing a Complex Layout
- Examples
Core Layout Principles
Master the fundamental Flutter layout rule: Constraints go down. Sizes go up. Parent sets position.
- Pass Constraints Down: Always pass constraints (minimum/maximum width and height) from the parent Widget to its children. A Widget cannot choose its own size independently of its parent's constraints.
- Pass Sizes Up: Calculate the child Widget's desired size within the given constraints and pass this size back up to the parent.
- Set Position via Parent: Define the and
xcoordinates of a child Widget exclusively within the parent Widget. Children do not know their own position on the screen.y - Avoid Unbounded Constraints: Never pass unbounded constraints (e.g., ) in the cross-axis of a flex box (
double.infinityorRow) or within scrollable regions (Column). This causes render exceptions.ListView
Structural Widgets
Select the appropriate structural Widget based on the required spatial arrangement.
- Use and
Row: ImplementColumnfor horizontal linear layouts andRowfor vertical linear layouts. Control child alignment usingColumnandmainAxisAlignment.crossAxisAlignment - Use and
Expanded: Wrap children ofFlexibleorRowinColumnto force them to fill available space, orExpandedto allow them to size themselves up to the available space.Flexible - Use : Wrap Widgets in a
Containerwhen you need to apply padding, margins, borders, or background colors.Container - Use : Implement
Stackwhen Widgets must overlap on the Z-axis. UseStackto anchor children to specific edges of thePositioned.Stack - Use : Enforce strict, tight constraints on a child Widget by wrapping it in a
SizedBoxwith explicitSizedBoxandwidthvalues.height
Adaptive and Responsive Design
Apply conditional logic to handle varying screen sizes and form factors.
- If fitting UI into available space (Responsive): Use ,
LayoutBuilder, andExpandedto dynamically adjust the size and placement of elements based on the parent's constraints.Flexible - If adjusting UI usability for a specific form factor (Adaptive): Use conditional rendering to swap entire layout structures. For example, render a bottom navigation bar on mobile, but a side navigation rail on tablets/desktop.
Workflow: Implementing a Complex Layout
Follow this sequential workflow to architect and implement robust Flutter layouts.
Task Progress
- Phase 1: Visual Deconstruction
- Break down the target UI into a hierarchy of rows, columns, and grids.
- Identify overlapping elements (requiring ).
Stack - Identify scrolling regions (requiring or
ListView).SingleChildScrollView
- Phase 2: Constraint Planning
- Determine which Widgets require tight constraints (fixed size) vs. loose constraints (flexible size).
- Identify potential unbounded constraint risks (e.g., a inside a
ListView).Column
- Phase 3: Implementation
- Build the layout from the outside in, starting with the and primary structural Widgets.
Scaffold - Extract deeply nested layout sections into separate, stateless Widgets to maintain readability.
- Build the layout from the outside in, starting with the
- Phase 4: Validation and Feedback Loop
- Run the application on target devices/simulators.
- Run validator -> review errors -> fix: Open the Flutter Inspector. Enable "Debug Paint" to visualize render boxes.
- Check for yellow/black striped overflow warnings.
- If overflow occurs: Wrap the overflowing Widget in (if inside a flex box) or wrap the parent in a scrollable Widget.
Expanded
Examples
Example: Resolving Unbounded Constraints in Flex Boxes
Anti-pattern: Placing a directly inside a causes an unbounded height exception because the provides infinite vertical space to the .
ListViewColumnColumnListViewdart
// BAD: Throws unbounded height exception
Column(
children: [
Text('Header'),
ListView(
children: [/* items */],
),
],
)Implementation: Wrap the in an Widget to bound its height to the remaining space in the .
ListViewExpandedColumndart
// GOOD: ListView is constrained to remaining space
Column(
children: [
Text('Header'),
Expanded(
child: ListView(
children: [/* items */],
),
),
],
)Example: Responsive Layout with LayoutBuilder
Implement to conditionally render different structural Widgets based on available width.
LayoutBuilderdart
Widget buildAdaptiveLayout(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
// Conditional logic based on screen width
if (constraints.maxWidth > 600) {
// Tablet/Desktop: Side-by-side layout
return Row(
children: [
SizedBox(width: 250, child: SidebarWidget()),
Expanded(child: MainContentWidget()),
],
);
} else {
// Mobile: Stacked layout with navigation
return Column(
children: [
Expanded(child: MainContentWidget()),
BottomNavigationBarWidget(),
],
);
}
},
);
}