Skip to main content

Creating Stack and Positioned Layouts

1. Using Stack Widget

Property Values Description
children List<Widget> Widgets to be stacked
alignment AlignmentGeometry Alignment of children within the stack
textDirection TextDirection Direction of text layout (LTR/RTL)
fit StackFit How to size the stack (expand, loose, tight)

Example: Basic Stack Usage

Stack(
  children: [
    Container(
      width: 200,
      height: 200,
      color: Colors.blue,
    ),
    Container(
      width: 150,
      height: 150,
      color: Colors.red,
    ),
  ],
)

Example: Positioned Children

Stack(
  children: [
    Container(
      width: 200,
      height: 200,
      color: Colors.blue,
    ),
    Positioned(
      top: 50,
      left: 50,
      child: Container(
        width: 100,
        height: 100,
        color: Colors.red,
      ),
    ),
  ],
)

2. Using Positioned Widget

Property Values Description
key Key? Unique identifier for the widget
left double? Distance from the left edge of the parent
top double? Distance from the top edge of the parent
right double? Distance from the right edge of the parent
bottom double? Distance from the bottom edge of the parent
width double? Width of the widget
height double? Height of the widget

Example: Basic Positioned Usage

Stack(
  children: [
    Positioned(
      left: 50.0,
      top: 50.0,
      child: Container(
        width: 100.0,
        height: 100.0,
        color: Colors.blue,
      ),
    ),
  ],
)

Example: Positioned with Right and Bottom

Stack(
  children: [
    Positioned(
      right: 20.0,
      bottom: 20.0,
      child: Container(
        width: 80.0,
        height: 80.0,
        color: Colors.red,
      ),
    ),
  ],
)
Note: The Positioned widget must be a direct child of a Stack widget.

3. Using IndexedStack Widget

The IndexedStack widget in Flutter is a layout widget that displays one child at a time from a list of children, based on an index. It is particularly useful for creating tab-like interfaces where only one tab content is visible at a time.

Property Description Values
index The index of the child to display. int
children A list of widgets to be displayed. List<Widget>
alignment Alignment of the stack's children. AlignmentGeometry
textDirection Text direction for the stack. TextDirection
clipBehavior How to clip the stack's children. Clip

Example: Using IndexedStack

IndexedStack(
  index: _currentIndex,
  children: [
    Text('Tab 1 Content'),
    Text('Tab 2 Content'),
    Text('Tab 3 Content'),
  ],
)
Note: The IndexedStack widget does not automatically manage the index state. You must handle the index change manually, typically using a TabBar or BottomNavigationBar.

4. Using Wrap Widget

The Wrap widget in Flutter is used to lay out its children in a horizontal or vertical direction, wrapping to a new line when the available space is exhausted. It's particularly useful for creating dynamic layouts that adapt to different screen sizes or content lengths.

Property Description Values
children List of widgets to be laid out List<Widget>
direction Direction in which the children are laid out Axis.horizontal or Axis.vertical
alignment Alignment of the children along the main axis WrapAlignment.start, WrapAlignment.center, etc.
runAlignment Alignment of the children along the cross axis WrapCrossAlignment.start, WrapCrossAlignment.center, etc.
runSpacing Space between each run of children double
spacing Space between each child in the same run double

Example: Basic Wrap Widget Usage

Wrap(
  spacing: 8.0,
  runSpacing: 4.0,
  children: <Widget>[
    Chip(label: Text('Flutter')),
    Chip(label: Text('Dart')),
    Chip(label: Text('UI')),
    Chip(label: Text('Mobile')),
  ],
)

Example: Wrap with Vertical Direction

Wrap(
  direction: Axis.vertical,
  spacing: 10.0,
  runSpacing: 5.0,
  children: <Widget>[
    Text('Item 1'),
    Text('Item 2'),
    Text('Item 3'),
  ],
)

5. Using Flow Widget

The Flow widget in Flutter provides a way to lay out children with custom positioning logic. It's particularly useful for complex layouts where the standard widgets don't provide enough control.

Property Description Values
delegate Required. Defines how children are positioned and sized. FlowDelegate
children Optional. List of child widgets to be laid out. List<Widget>

Example: Basic Flow Layout

import &#x27;package:flutter/material.dart&#x27;;

class FlowExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Flow Example")),
      body: Flow(
        delegate: MyFlowDelegate(),
        children: [
          Container(color: Colors.red, width: 50, height: 50),
          Container(color: Colors.blue, width: 50, height: 50),
          Container(color: Colors.green, width: 50, height: 50),
        ],
      ),
    );
  }
}

class MyFlowDelegate extends FlowDelegate {
  @override
  void paintChildren(FlowPaintingContext context) {
    // Custom painting logic here
    for (int i = 0; i < context.childCount; i++) {
      context.paintChild(i, transform: Matrix4.translationValues(i * 60, 0, 0));
    }
  }

  @override
  bool shouldRepaint(covariant FlowDelegate oldDelegate) {
    return false;
  }
}
Note: The Flow widget is generally not recommended for most use cases due to its complexity and performance implications. Consider using CustomPaint or other layout widgets for more efficient custom layouts.

6. Using Table Widget

Property Values Description
children List<TableRow> Required. The rows of the table.
columnWidths Map<int, TableColumnWidth> Optional. Controls the width of each column.
defaultColumnWidth TableColumnWidth Optional. Default width for columns not specified in columnWidths.
dividerThickness double Optional. Thickness of the divider lines between rows and columns.
horizontalAlignment CrossAxisAlignment Optional. Alignment of children within each cell horizontally.
inner BoxGeometry Optional. The inner geometry of the table.
outer BoxGeometry Optional. The outer geometry of the table.
textBaseline TextBaseline Optional. The text baseline to use for aligning the rows.
textDirection TextDirection Optional. The text direction to use for aligning the columns.
verticalAlignment VerticalAlignment Optional. Alignment of children within each cell vertically.

Example: Basic Table Widget Usage

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Table Example")),
        body: Padding(
          padding: EdgeInsets.all(16.0),
          child: Table(
            children: [
              TableRow(
                children: [
                  TableCell(child: Text("Name")),
                  TableCell(child: Text("Age")),
                ],
              ),
              TableRow(
                children: [
                  TableCell(child: Text("Alice")),
                  TableCell(child: Text("25")),
                ],
              ),
              TableRow(
                children: [
                  TableCell(child: Text("Bob")),
                  TableCell(child: Text("30")),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

7. Using CustomMultiChildLayout Widget

The CustomMultiChildLayout widget in Flutter allows you to create custom layout behaviors for multiple children. It provides fine-grained control over how each child is positioned and sized within the layout.

Property Description Values
delegate The layout delegate that defines how children are laid out. CustomMultiChildLayoutDelegate
children The list of child widgets to be laid out. List<Widget>

Example: Using CustomMultiChildLayout

class CustomLayoutDelegate extends CustomMultiChildLayoutDelegate {
  @override
  void performLayout(BuildContext context) {
    final size = getSize(context);
    // Position children manually
    layoutChild('child1', BoxConstraints.tight(Size(100, 100)));
    positionChild('child1', Offset(20, 20));
  }

  @override
  bool shouldRelayout(CustomMultiChildLayoutDelegate oldDelegate) {
    return false;
  }
}

class CustomLayoutWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CustomMultiChildLayout(
      delegate: CustomLayoutDelegate(),
      children: [
        LayoutId(
          id: 'child1',
          child: Container(
            color: Colors.blue,
            child: Text('Child 1'),
          ),
        ),
      ],
    );
  }
}
Note: CustomMultiChildLayout is useful for complex custom layouts where standard widgets like Stack or Positioned do not provide enough flexibility.

8. Using LayoutBuilder Widget

The LayoutBuilder widget is a powerful tool for creating responsive layouts in Flutter. It allows you to build widgets that adapt their design based on the available space provided by their parent.

Property Description Values
builder Callback function that builds the widget tree based on the constraints provided. (BuildContext context, BoxConstraints constraints) => Widget

Example: Using LayoutBuilder to adapt layout based on screen size

import &#x27;package:flutter/material.dart&#x27;;

class ResponsiveLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth < 600) {
          return Column(
            children: [
              Text("Mobile View"),
              Text("Narrow screen detected"),
            ],
          );
        } else {
          return Row(
            children: [
              Text("Desktop View"),
              Text("Wide screen detected"),
            ],
          );
        }
      },
    );
  }
}
Note: LayoutBuilder is particularly useful for creating adaptive UIs that respond to different screen sizes or orientations without relying on MediaQuery.

Key Points

  • LayoutBuilder provides constraints from its parent, which can be used to make layout decisions.
  • It is ideal for creating responsive layouts that adapt to different screen sizes.
  • Unlike MediaQuery, it does not depend on global screen metrics but rather on the local constraints.

9. Using Transform Widget

The Transform widget in Flutter allows you to apply 2D or 3D transformations to its child widget. It is commonly used for rotating, scaling, translating, or skewing UI elements.

Property Description Values
transform The transformation matrix to apply to the child widget. Matrix4
alignment Defines the alignment point of the transformation. AlignmentGeometry
origin Defines the origin point for the transformation. Offset

Example: Rotating a Widget

<Transform
  transform: Matrix4.rotationZ(0.5),
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
/>

Example: Scaling a Widget

<Transform
  transform: Matrix4.scaling(1.5),
  child: Text('Scaled Text'),
/>
Note: The Transform widget does not change the layout of its child; it only visually transforms it. For layout changes, consider using Stack or Positioned.

10. Using DecoratedBox Widget

The DecoratedBox widget in Flutter is used to draw a decoration behind its child. It's particularly useful for adding backgrounds, borders, shadows, and other visual effects to widgets.

Property Description Values
decoration Defines the decoration to be drawn behind the child. BoxDecoration or ShapeDecoration
child The widget to be displayed inside the decoration. Widget

Example: Basic DecoratedBox with BoxDecoration

DecoratedBox(
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(10),
    boxShadow: [
      BoxShadow(
        color: Colors.grey.withOpacity(0.5),
        spreadRadius: 2,
        blurRadius: 5,
        offset: Offset(0, 3),
      ),
    ],
  ),
  child: Container(
    padding: EdgeInsets.all(16),
    child: Text('Hello, DecoratedBox!'),
  ),
)
Note: The DecoratedBox does not affect the layout of its child; it only draws the decoration behind it.

Example: Using ShapeDecoration

DecoratedBox(
  decoration: ShapeDecoration(
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(15),
      side: BorderSide(color: Colors.red, width: 2),
    ),
    color: Colors.yellow,
  ),
  child: Padding(
    padding: EdgeInsets.all(10),
    child: Text('Rounded Border with Yellow Background'),
  ),
)

Was this article helpful?