Back to Posts

Flutter Layout Widgets: Structuring UI

12 min read

Layout widgets are essential for organizing and structuring user interfaces in Flutter applications. Let's explore the various layout widgets and how to use them effectively.

1. Basic Layout Widgets

Row and Column

class RowColumnExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          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,
            ),
          ],
        ),
        SizedBox(height: 20),
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          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,
            ),
          ],
        ),
      ],
    );
  }
}

Stack

class StackExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          width: 200,
          height: 200,
          color: Colors.blue,
        ),
        Positioned(
          top: 20,
          left: 20,
          child: Container(
            width: 50,
            height: 50,
            color: Colors.red,
          ),
        ),
        Positioned(
          bottom: 20,
          right: 20,
          child: Container(
            width: 50,
            height: 50,
            color: Colors.green,
          ),
        ),
      ],
    );
  }
}

2. Advanced Layout Widgets

Expanded and Flexible

class ExpandedFlexibleExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          flex: 2,
          child: Container(
            height: 100,
            color: Colors.red,
          ),
        ),
        Flexible(
          flex: 1,
          child: Container(
            height: 100,
            color: Colors.green,
          ),
        ),
        Expanded(
          flex: 3,
          child: Container(
            height: 100,
            color: Colors.blue,
          ),
        ),
      ],
    );
  }
}

Wrap

class WrapExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Wrap(
      spacing: 8.0,
      runSpacing: 8.0,
      children: List.generate(
        10,
        (index) => Chip(
          label: Text('Item $index'),
          backgroundColor: Colors.blue,
        ),
      ),
    );
  }
}

3. Custom Layout Widgets

Custom Layout Builder

class CustomLayoutBuilder extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth > 600) {
          return Row(
            children: [
              Container(
                width: 200,
                color: Colors.blue,
                child: Center(child: Text('Sidebar')),
              ),
              Expanded(
                child: Container(
                  color: Colors.green,
                  child: Center(child: Text('Content')),
                ),
              ),
            ],
          );
        } else {
          return Column(
            children: [
              Container(
                height: 100,
                color: Colors.blue,
                child: Center(child: Text('Header')),
              ),
              Expanded(
                child: Container(
                  color: Colors.green,
                  child: Center(child: Text('Content')),
                ),
              ),
            ],
          );
        }
      },
    );
  }
}

Custom MultiChildLayout

class CustomMultiChildLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CustomMultiChildLayoutDelegate(
      children: [
        LayoutId(
          id: 'header',
          child: Container(
            color: Colors.blue,
            child: Center(child: Text('Header')),
          ),
        ),
        LayoutId(
          id: 'content',
          child: Container(
            color: Colors.green,
            child: Center(child: Text('Content')),
          ),
        ),
        LayoutId(
          id: 'footer',
          child: Container(
            color: Colors.red,
            child: Center(child: Text('Footer')),
          ),
        ),
      ],
    );
  }
}

class CustomMultiChildLayoutDelegate extends MultiChildLayoutDelegate {
  @override
  void performLayout(Size size) {
    if (hasChild('header')) {
      layoutChild('header', BoxConstraints.tight(Size(size.width, 100)));
      positionChild('header', Offset.zero);
    }

    if (hasChild('content')) {
      layoutChild('content', BoxConstraints.tight(Size(size.width, size.height - 200)));
      positionChild('content', Offset(0, 100));
    }

    if (hasChild('footer')) {
      layoutChild('footer', BoxConstraints.tight(Size(size.width, 100)));
      positionChild('footer', Offset(0, size.height - 100));
    }
  }

  @override
  bool shouldRelayout(CustomMultiChildLayoutDelegate oldDelegate) => false;
}

4. Best Practices

  1. Implement proper layout

    • Choose appropriate layout widgets
    • Handle different screen sizes
    • Consider layout constraints
  2. Enhance layout structure

    • Use proper spacing
    • Implement responsive design
    • Consider accessibility
  3. Optimize layout performance

    • Minimize layout passes
    • Use const constructors
    • Handle memory efficiently

By mastering these layout widgets and following best practices, you can create Flutter applications that are:

  • More organized
  • More responsive
  • More maintainable
  • More efficient