free geoip
7

Expanded and Flexible Widgets Explained

When building responsive layouts in Flutter, two important widgets often come into play: Expanded and Flexible. These widgets allow developers…

When building responsive layouts in Flutter, two important widgets often come into play: Expanded and Flexible. These widgets allow developers to control how child widgets behave inside Row, Column, or Flex layouts. Understanding the difference between them is crucial for creating adaptive UI designs that work across various screen sizes. In this article, we will explore what Expanded and Flexible widgets are, how they differ, and provide practical examples with source code you can directly use in your Flutter projects.

What is the Expanded Widget?

The Expanded widget in Flutter forces a child of a Row, Column, or Flex to expand and fill the available space along the main axis. Expanded takes as much space as possible, depending on the flex property value. By default, flex: 1.

Example of Expanded:

import 'package:flutter/material.dart';

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

class MyExpandedExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Expanded Example')),
        body: Row(
          children: [
            Expanded(
              flex: 2,
              child: Container(
                color: Colors.red,
                child: Center(child: Text('Expanded Flex 2')),
              ),
            ),
            Expanded(
              flex: 1,
              child: Container(
                color: Colors.blue,
                child: Center(child: Text('Expanded Flex 1')),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

In this example, the red container takes twice the space of the blue container because its flex value is 2 while the other is 1.

What is the Flexible Widget?

The Flexible widget gives its child the flexibility to either fill the available space or keep its natural size, depending on the fit property. The fit property can be either FlexFit.tight or FlexFit.loose.

  • FlexFit.tight: Forces the child to fill the available space (similar to Expanded).
  • FlexFit.loose: Lets the child occupy only as much space as it needs.

Example of Flexible:

import 'package:flutter/material.dart';

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

class MyFlexibleExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Flexible Example')),
        body: Row(
          children: [
            Flexible(
              flex: 1,
              fit: FlexFit.tight,
              child: Container(
                color: Colors.green,
                child: Center(child: Text('Tight Flexible')),
              ),
            ),
            Flexible(
              flex: 1,
              fit: FlexFit.loose,
              child: Container(
                color: Colors.orange,
                width: 100,
                child: Center(child: Text('Loose Flexible')),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Here, the green box behaves like an Expanded widget because it uses FlexFit.tight, while the orange box keeps its natural width due to FlexFit.loose.

Comparison Between Expanded and Flexible

Although Expanded is essentially a shortcut for Flexible(fit: FlexFit.tight), it is often used for simplicity. Flexible, however, provides more customization because you can choose between tight and loose fitting.

PropertyExpandedFlexible
Default FitAlways tightCan be tight or loose
Space UsageFills all available spaceCan fill or keep natural size
Flex ControlYes, via flexYes, via flex + fit
Use CaseWhen child must expand fullyWhen child may expand or stay natural

Practical Use Case Example

Let’s consider a case where you want to create a layout with a header, a body section that expands, and a footer that only takes as much space as needed. Here is how you can achieve that using Expanded and Flexible together.

import 'package:flutter/material.dart';

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

class MyUseCaseExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Expanded vs Flexible')),
        body: Column(
          children: [
            Container(
              color: Colors.purple,
              height: 60,
              child: Center(child: Text('Header - Fixed Size')),
            ),
            Expanded(
              flex: 3,
              child: Container(
                color: Colors.yellow,
                child: Center(child: Text('Body - Expanded')),
              ),
            ),
            Flexible(
              flex: 1,
              fit: FlexFit.loose,
              child: Container(
                color: Colors.grey,
                height: 80,
                child: Center(child: Text('Footer - Flexible Loose')),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

In this example:

  • The header has a fixed height.
  • The body expands to take up most of the available space.
  • The footer only takes the space it needs, thanks to Flexible with FlexFit.loose.

Conclusion

Understanding the differences between Expanded and Flexible widgets in Flutter is key for building responsive and adaptive UI layouts. Expanded always forces its child to occupy available space, while Flexible provides more control with tight and loose fitting. By combining these two widgets, you can achieve a wide variety of layout behaviors for your mobile apps.

For more details about layout widgets in Flutter, you can also check the official documentation at Flutter Layout Widgets.

rysasahrial

Leave a Reply

Your email address will not be published. Required fields are marked *