Flutter Widget ( Expanded & Flexible ) The Whole Picture.
Flutter Widgets ( Expanded & Flexible ) The Whole Picture.

Flutter Widgets ( Expanded & Flexible ) The Whole Picture.

Murtaza Sulaihi
Flutter Community
6 min readSep 11, 2020

--

I am sure you all must have gone through the official documentation regarding the Expanded and Flexible Widgets because that's what everyone tells you to do, to read the official documentation on flutter.io. Well, I am leaving a link below if you want to read it. ( you may skip it )

Official Documentation: https://api.flutter.dev/flutter/widgets/Expanded-class.html

What is Expanded Widget? A widget that expands a child inside a Row or a Column. This widget needs to be used inside a Row or Column widget for it to work properly, it takes up all the available space along its main axis and if all the widgets are wrapped around Expanded widget inside a Row or a Column then space will be divided equally.

Flexible widget is basically the same as the Expanded widget, but there is a slight difference in the properties which makes Flexible widget as the name suggests flexible to use.

so let's check out what is all the fuss about…

Expanded widget properties.

          Expanded(
flex: 1,// default
child: Container(),// required field
),

What is the flex value? if you have worked with Android Studio and Constraint layouts in it, you might be familiar with weight, which decides the priority for the space given to a widget. Distribution of space is according to the weight mentioned in Constraint layouts. Flex value is exactly the same thing. In a Row or a Column if you want a single widget to take up more space than the other change the flex value and see the difference it makes.

Expanded widget with Row.

Scaffold(
appBar: AppBar(
title: Text('Expanded Widget with Row'),
backgroundColor: Colors.blue,
),
body: Row(
children: <Widget>[
Container(
alignment: Alignment.center,
color: Colors.amber,
height: 100,
width: 100,
child: Text('Container 1'),
),
Expanded(
child: Container(
alignment: Alignment.center,
height: 100,
color: Colors.green,
child: Text(
'Container 2 Expanded',
textAlign: TextAlign.center,
),
),
),

Container(
alignment: Alignment.center,
height: 100,
width: 100,
color: Colors.amber,
child: Text('Container 3'),
),
],
),
),
);

The above code is going to produce the result in the image below.

Expanded widget wrapped around Container 2 inside Row widget.

As you can see Container 2 is a child of Row and it is also wrapped with Expanded widget which produces the above result. Are you wondering how it will look without the Expanded widget?

       Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
alignment: Alignment.center,
color: Colors.amber,
height: 100,
width: 100,
child: Text('Container 1'),
),
Container(
alignment: Alignment.center,
height: 100,
width: 100,
color: Colors.green,
child: Text(
'Container 2',
textAlign: TextAlign.center,
),
),

There are two properties that I changed if you compare the two codes I have highlighted those, first: I have added MainAxisAligment in Row, second: I have added width to the Container 2, which produces the result as in the image below.

Container 2 is not wrapped inside an Expanded Widget.

I will leave tips and tricks for the last…

Expanded widget with Column

Scaffold(
appBar: AppBar(
title: Text('Expanded Widget Column'),
backgroundColor: Colors.blue,
),
body: Center(
child: Column(
children: <Widget>[
Container(
alignment: Alignment.center,
color: Colors.amber,
height: 100,
width: 100,
child: Text('Container 1'),
),
Expanded(
child: Container(
alignment: Alignment.center,
width: 100,
color: Colors.green,
child: Text(
'Container 2 Expanded',
textAlign: TextAlign.center,
),
),
),

Container(
alignment: Alignment.center,
height: 100,
width: 100,
color: Colors.amber,
child: Text('Container 3'),
),
],
),

The code is almost similar to the Row that I have written earlier, the difference is now we seeing Expanded widget wrapped around a child inside a Column widget. see the image below…

Container 2 is wrapped with Expanded widget inside a Column widget.

I am not posting the code which shows how it will look without the Expanded widget inside a Column, it will just make it lengthier. Just remove the Expanded widget, add height to the Container 2 and add MainAxisAlignment.spaceEvenly to the Column widget and you are good to go.

Now let's talk about the Flexible widget a little.

Official documentation: https://api.flutter.dev/flutter/widgets/Flexible-class.html

Flexible widget controls its child’s flexibility to expand and fill the available space in the main axis of a Row or a Column, the difference between Expanded widget and Flexible widget is, Flexible does not require the child to fill the available space.

let’s check out the code to understand better…

        Flexible(
flex: 1, // default value
fit: FlexFit.loose, //default value
child: Container(), // required field
),

The above code is what makes it different from Expanded widget. The fit property is the main difference if you change it to FlexFit.tight then it acts exactly as the Expanded widget.

Flexible widget with Row

      Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Flexible(
fit: FlexFit.loose,
child: Container(
alignment: Alignment.center,
color: Colors.amber,
height: 100,
width: 80,
child: Text('Container 1'),
),
),
Flexible(
flex: 2,
fit: FlexFit.loose,

child: Container(
alignment: Alignment.center,
height: 100,
width: 100,
color: Colors.green,
child: Text(
'Container 2',
textAlign: TextAlign.center,
),
),
),
Flexible(
flex: 3,
fit: FlexFit.loose,

child: Container(
alignment: Alignment.center,
height: 100,
width: 120,
color: Colors.amber,
child: Text('Container 3'),
),
),
],
),

If you look closely and compare the codes between Flexible widget with Row and Expanded widget with Row, the major difference that you will notice that when using Expanded widget, MainAxisAlignment and width will be ignored (though it has not been mentioned in the code ) but in Flexible widget, you can use both properties to shape or position your child widget inside a Row or a Column. Using Flexible widget resizes its widgets according to parent size, it is determined by the flex value mentioned and fit property.

please look at the image below…

I have been mentioning MainAxisAlignment a lot in the article, let me show what I exactly mean by it…

It is an important property of a Row widget as well as a Column widget, will discuss more in detail when I write about it, but just for the sake of understanding here is the graphical representation of it.

MainAxis of a Column and a Row Widget.

I hope I have covered everything that is about Expanded widget and Flexible widget. As promised earlier let me write a few tips.

Tips and Tricks

  1. Repeating again, mainAxisAlignnment will be ignored in Row and Column widget, and also height will be ignored in case of a child is wrapped around Expanded widget inside Column and width will be ignored in the Row.
  2. If you are still looking for any kind of space between widgets while wrapped inside of an Expanded widget, then wrap the child of Expanded with Padding to get little space in between widgets.
  3. If you want more control over spacing and positioning your widget inside a Row or a Column then use Flexible instead of Expanded.

That all! for this article, lengthier than the last one, well you avid readers encouraged me to write again. Keep reading and sharing and clapping!

always remember: Discovery requires experimentation.

You can also support me by having a Cup of Coffee ☕️ with me.

--

--

Murtaza Sulaihi
Flutter Community

By profession, I am a school professor and I also develop Android applications and also Flutter applications.