Layout Widgets in Flutter

Flutter Architecture  Layout Widgets in Flutter

Layout Widgets in Flutter

In Flutter, layout widgets play a key role in arranging and positioning other widgets on the screen. They help you build responsive, flexible, and visually organized user interfaces.


Type of LayoutWidgets

Layout widgets can be grouped into two distinct category based on its child:

  • 1. Single-Child Layout Widgets
  • 2. Multi-Child Layout Widgets

  • 1. Single-Child Layout Widgets

    These widgets are designed to hold only one child. They’re perfect when you need to wrap a widget to control its position, add padding, alignment, or apply styling.Here are some commonly used single-child layout widgets:

    Container

    A versatile box that wraps a single widget. You can use it to apply padding, margins, borders, background color, and more.

    
      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('Container Example'),
              ),
              body: Center(
                child: Container(
                  width: 200,
                  height: 100,
                  color: Colors.blue,
                  child: Center(
                    child: Text(
                      'Hello, Flutter!',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ),
              ),
            ),
          );
        }
      }
    

    Align

    Aligns its child within itself based on the alignment you choose (e.g., topLeft, center, bottomRight, etc.).

    
      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('Align Widget Example'),
              ),
              body: Center(
                child: Align(
                  alignment: Alignment.topRight,
                  child: Text('Aligned text'),
                ),
              ),
            ),
          );
        }
      }
    

    Padding

    Adds empty space around its child. This helps give breathing room between widgets, improving the visual layout.

    
      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('Padding Example'),
              ),
              body: Center(
                child: Padding(
                  padding: EdgeInsets.all(16.0), // Adds padding on all sides
                  child: Container(
                    color: Colors.blue,
                    child: Text(
                      'Hello, Flutter!',
                      style: TextStyle(color: Colors.white, fontSize: 24),
                    ),
                  ),
                ),
              ),
            ),
          );
        }
      }
    

    Center

    Places its child widget exactly at the center of the parent widget (both vertically and horizontally).

    
      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('Center Widget Example'),
              ),
              body: Center(
                child: Container(
                  color: Colors.orange,
                  width: 200,
                  height: 100,
                  child: Center(
                    child: Text(
                      'Centered Text',
                      style: TextStyle(color: Colors.white, fontSize: 24),
                    ),
                  ),
                ),
              ),
            ),
          );
        }
      }
    

    SizedBox

    Creates a box with a specific width and height. It’s useful when you want fixed spacing or a fixed size for a widget.

    
      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('SizedBox Example'),
              ),
              body: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                      color: Colors.blue,
                      width: 100,
                      height: 100,
                      child: Center(child: Text('Box 1')),
                    ),
                    SizedBox(height: 20), // Adds vertical space between the boxes
                    Container(
                      color: Colors.red,
                      width: 100,
                      height: 100,
                      child: Center(child: Text('Box 2')),
                    ),
                  ],
                ),
              ),
            ),
          );
        }
      }
    

    FractionallySizedBox

    Sizes its child to a fraction of the available space. For example, if widthFactor: 0.5, the child will take up 50% of the width of its parent.

    
      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('FractionallySizedBox Example'),
              ),
              body: Center(
                child: FractionallySizedBox(
                  alignment: Alignment.center,
                  widthFactor: 0.5, // 50% of available width
                  heightFactor: 0.3, // 30% of available height
                  child: Container(
                    color: Colors.green,
                    child: Center(
                      child: Text(
                        'Half Width & 30% Height',
                        style: TextStyle(color: Colors.white),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          );
        }
      }
    

    Multiple Child Widgets

    Multi-child layout widgets are used when a widget needs to manage and display more than one child widget. Each multi-child layout widget arranges its children in a unique way.

    1. Arranges its children horizontally, side by side.
    2. Arranges its children vertically, one on top of the other.
    3. Displays children as a scrollable list. Ideal for dynamic lists of data.
    4. Organizes children in a grid, like a gallery layout.
    5. Places children in a horizontal or vertical line and wraps them to the next line if there’s not enough space.
    6. Arranges widgets in a grid format using rows and columns. Great for displaying tabular data.
    7. Gives you total control by letting you define your own layout logic using a custom LayoutDelegate.

    ListView

    
      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('ListView Example'),
              ),
              body: ListView(
                children: [
                  ListTile(title: Text('Item 1')),
                  ListTile(title: Text('Item 2')),
                  ListTile(title: Text('Item 3')),
                ],
              ),
            ),
          );
        }
      }
    

    GridView

    
      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('GridView Example'),
              ),
              body: GridView.count(
                crossAxisCount: 2, // Number of columns
                children: [
                  Container(color: Colors.blue, child: Center(child: Text('Box 1'))),
                  Container(color: Colors.red, child: Center(child: Text('Box 2'))),
                  Container(color: Colors.green, child: Center(child: Text('Box 3'))),
                  Container(color: Colors.yellow, child: Center(child: Text('Box 4'))),
                ],
              ),
            ),
          );
        }
      }
    

    Wrap

    
      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('Wrap Example'),
              ),
              body: Wrap(
                spacing: 10.0, // Space between children horizontally
                runSpacing: 10.0, // Space between lines
                children: [
                  Chip(label: Text('Chip 1')),
                  Chip(label: Text('Chip 2')),
                  Chip(label: Text('Chip 3')),
                  Chip(label: Text('Chip 4')),
                ],
              ),
            ),
          );
        }
      }
    

    Table

    
      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: Table(
                border: TableBorder.all(color: Colors.black), // Adds borders
                children: [
                  TableRow(children: [
                    Text('Header 1', textAlign: TextAlign.center),
                    Text('Header 2', textAlign: TextAlign.center),
                    Text('Header 3', textAlign: TextAlign.center),
                  ]),
                  TableRow(children: [
                    Text('Row 1, Col 1'),
                    Text('Row 1, Col 2'),
                    Text('Row 1, Col 3'),
                  ]),
                ],
              ),
            ),
          );
        }
      }
    

    CustomMultiChildLayout

    
      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('CustomMultiChildLayout Example'),
              ),
              body: CustomMultiChildLayout(
                delegate: MyCustomLayoutDelegate(),
                children: [
                  LayoutId(
                    id: 'box1',
                    child: Container(color: Colors.blue, width: 50, height: 50),
                  ),
                  LayoutId(
                    id: 'box2',
                    child: Container(color: Colors.red, width: 100, height: 50),
                  ),
                ],
              ),
            ),
          );
        }
      }
    
      class MyCustomLayoutDelegate extends MultiChildLayoutDelegate {
        @override
        void performLayout(Size size) {
          if (hasChild('box1')) {
            layoutChild('box1', BoxConstraints.loose(size));
            positionChild('box1', Offset(0, 0));
          }
          if (hasChild('box2')) {
            layoutChild('box2', BoxConstraints.loose(size));
            positionChild('box2', Offset(60, 60));
          }
        }
    
        @override
        bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate) => false;
      }
    

    Dashboard with Rows, Columns, and Cards

    
      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('Dashboard Layout'),
              ),
              body: Column(
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                      _buildCard('Item 1', Colors.blue),
                      _buildCard('Item 2', Colors.red),
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                      _buildCard('Item 3', Colors.green),
                      _buildCard('Item 4', Colors.orange),
                    ],
                  ),
                ],
              ),
            ),
          );
        }
    
        Widget _buildCard(String title, Color color) {
          return Card(
            color: color,
            child: Container(
              width: 100,
              height: 100,
              child: Center(
                child: Text(
                  title,
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
          );
        }
      }
    

    2. Responsive Grid Layout

    
      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('Responsive Grid Layout'),
              ),
              body: LayoutBuilder(
                builder: (context, constraints) {
                  int crossAxisCount = constraints.maxWidth > 600 ? 4 : 2;
                  return GridView.count(
                    crossAxisCount: crossAxisCount,
                    children: List.generate(8, (index) {
                      return Container(
                        margin: EdgeInsets.all(8.0),
                        color: Colors.teal[100 * ((index % 8) + 1)],
                        child: Center(
                          child: Text('Item $index'),
                        ),
                      );
                    }),
                  );
                },
              ),
            ),
          );
        }
      }
    

    Custom Scroll View with Slivers

    
      import 'package:flutter/material.dart';
    
      void main() {
        runApp(MyApp());
      }
    
      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            home: Scaffold(
              body: CustomScrollView(
                slivers: [
                  SliverAppBar(
                    expandedHeight: 200.0,
                    flexibleSpace: FlexibleSpaceBar(
                      title: Text('Sliver AppBar'),
                      background: Image.network(
                        'https://via.placeholder.com/300',
                        fit: BoxFit.cover,
                      ),
                    ),
                  ),
                  SliverList(
                    delegate: SliverChildBuilderDelegate(
                      (context, index) {
                        return ListTile(
                          title: Text('Item #$index'),
                        );
                      },
                      childCount: 20,
                    ),
                  ),
                ],
              ),
            ),
          );
        }
      }
    
    أحدث أقدم