Flutter - Flexible Widget - GeeksforGeeks

21 Feb, 2022
Flexible is a built-in widget in flutter which controls how a child of base flex widgets that are Row, Column, and Flex will fill the space available to it. The Expanded widget in flutter is shorthand of Flexible with the default fit of FlexFit.tight. Flexible widget plays a very important part in making a responsive app that looks and feels the same across multiple device sizes. But if one wants just basic filling up of spaces by widgets, then Expanded is also a good candidate for that.
const Flexible(
{Key key,
int flex: 1,
FlexFit fit: FlexFit.loose,
@required Widget child}
)
debugTypicalAncestorWidgetClass: This property takes Type as a parameter to set the ParentData for error messages.
fit: This property takes FlexFit value as a parameter. It decides how a Flexible child widget will fill the space available to it. A child widget can choose to take the maximum area with FlexFit.tight value or it can choose a minimum area with FlexFit.loose value. Or it can be assigned FlexFit.values.
flex: This property takes an integer as a parameter. It decides the size of the child widget along the main-axis (for Row it is horizontal and vertical for Column) with respect to other children widgets.
Example 1: Non-Responsive App
Dart
import 'package:flutter/material.dart'; void main() {  runApp(MaterialApp(    home: Scaffold(        appBar: AppBar(            title: Text('GeeksforGeeks'),            backgroundColor: Colors.greenAccent[400],            leading: IconButton(              icon: Icon(Icons.menu),              onPressed: () {},              tooltip: 'Menu',            ) //IconButton            ), //AppBar        body: Center(          child: Container(              child: Padding(            padding: const EdgeInsets.all(14.0),            child: Column(              children: <Widget>[                Row(                  children: <Widget>[                    Container(                      width: 175,                      height: 175,                      decoration: BoxDecoration(                        borderRadius: BorderRadius.circular(10),                        color: Colors.red,                      ), //BoxDecoration                    ), //Container                    SizedBox(                      width: 20,                    ), //SizedBox                    Container(                        width: 175,                        height: 175,                        decoration: BoxDecoration(                          borderRadius: BorderRadius.circular(10),                          color: Colors.red,                        ) //BoxDecoration                        ) //Container                  ], //<Widget>[]                  mainAxisAlignment: MainAxisAlignment.center,                ), //Row                Container(                  width: 380,                  height: 200,                  decoration: BoxDecoration(                      borderRadius: BorderRadius.circular(10),                      color: Colors.blue), //BoxDecoration                ), //Container                Row(                  children: <Widget>[                    Container(                      width: 180,                      height: 300,                      decoration: BoxDecoration(                        borderRadius: BorderRadius.circular(10),                        color: Colors.cyan,                      ), //BoxDecoration                    ), //Container                    SizedBox(                      width: 20,                    ), //SizedBox                    Container(                        width: 180,                        height: 300,                        decoration: BoxDecoration(                          borderRadius: BorderRadius.circular(10),                          color: Colors.cyan,                        ) //BoxedDecoration                        ) //Container                  ], //<Widget>[]                  mainAxisAlignment: MainAxisAlignment.center,                ), //Row              ], //<widget>[]              mainAxisAlignment: MainAxisAlignment.spaceBetween,              crossAxisAlignment: CrossAxisAlignment.center,            ), //Column          ) //Padding              ), //Container        ) //Center        ), //Scaffold     debugShowCheckedModeBanner: false,  )); //MaterialApp}
Output:
Explanation:  Taking a look at the code we can see that at the top of the screen we have a basic app bar build with AppBar widget containing a leading menu IconButton inside. The background color of the app bar is greenAccent[400] and the icon is having a tooltip saying ‘menu’. In the body of the app, the parent widget is Center followed by Container and Padding. After that, we have a Column widget which is taking a list of widgets as children. In that list, the first widget is a Row which is having two Containers and a SizedBox inside it. The Containers are given a height and width of 175 each and with the help of decoration property the color is set to red and the border-radius to 10. Next is a Container outside the Row with a width of 380 and a height of 200. The color is set to blue and the border-radius to 10. This is followed by another Row containing two Containers inside each having cyan color, a height of 300, and a width of 180. In between the containers, there is a SizedBox widget having a width of 20. In both rows, the main axis-alignment is set to center and in the column, the main axis-alignment is set to spaceBetween the cross axis-alignment is set to center.
We can see in this app there are five containers that do not change their size according to the screen size which means the widgets are not responsive. 
Example 2: Horizontally responsive app.
Dart
import 'package:flutter/material.dart'; void main() {  runApp(MaterialApp(    home: Scaffold(        appBar: AppBar(            title: Text('GeeksforGeeks'),            backgroundColor: Colors.greenAccent[400],            leading: IconButton(              icon: Icon(Icons.menu),              onPressed: () {},              tooltip: 'Menu',            ) //IconButton            ), //AppBar        body: Center(          child: Container(              child: Padding(            padding: const EdgeInsets.all(14.0),            child: Column(              children: <Widget>[                Row(                  children: <Widget>[                    Flexible(                      flex: 1,                      fit: FlexFit.tight,                      child: Container(                        height: 175,                        decoration: BoxDecoration(                          borderRadius: BorderRadius.circular(10),                          color: Colors.red,                        ), //BoxDecoration                      ), //Container                    ), //Flexible                    SizedBox(                      width: 20,                    ), //SizedBox                    Flexible(                      flex: 1,                      fit: FlexFit.loose,                      child: Container(                          height: 175,                          decoration: BoxDecoration(                            borderRadius: BorderRadius.circular(10),                            color: Colors.red,                          ) //BoxDecoration                          ), //Container                    ) //Flexible                  ], //<Widget>[]                  mainAxisAlignment: MainAxisAlignment.center,                ), //Row                Flexible(                  flex: 1,                  fit: FlexFit.loose,                  child: Container(                    width: 380,                    height: 200,                    decoration: BoxDecoration(                        borderRadius: BorderRadius.circular(10),                        color: Colors.blue), //BoxDecoration                  ), //Container                ), //Flexible                Row(                  children: <Widget>[                    Flexible(                      flex: 2,                      fit: FlexFit.tight,                      child: Container(                        width: 180,                        height: 300,                        decoration: BoxDecoration(                          borderRadius: BorderRadius.circular(10),                          color: Colors.cyan,                        ), //BoxDecoration                      ), //Container                    ), //Flexible                    SizedBox(                      width: 20,                    ), //SizedBox                    Flexible(                        flex: 2,                        fit: FlexFit.tight,                        child: Container(                            width: 180,                            height: 300,                            decoration: BoxDecoration(                              borderRadius: BorderRadius.circular(10),                              color: Colors.cyan,                            ) //BoxDecoration                            ) //Container,                        ) //Flexible                  ], //<widget>[]                  mainAxisAlignment: MainAxisAlignment.center,                ), //Row              ], //<Widget>[]              mainAxisAlignment: MainAxisAlignment.spaceBetween,              crossAxisAlignment: CrossAxisAlignment.center,            ), //Column          ) //Padding              ), //Container        ) //Center        ), //Scaffold     debugShowCheckedModeBanner: false,  )); //MaterialApp}
Output:
Explanation: Again by taking a look at the code of the app we can see that this time each Container widget is rapped with the Flexible widget. Inside the Container widgets in the top Row, the flex property is set to 1 for both the Containers which controls how the area will be distributed among these, and the fit property is set to FlexFlit.loose for both which makes sure that both these containers widgets have the option to take minimum area. And again for the blue Container, the flex property is set to 1, and the fit property is set to FlexFlit.loose. In the Container widgets of the bottom Row the flex property is set to 2, they are also going to take equal half-space, we have achieved the same result by making the flex to 1 in the Top Row. And the fit, in this case, is set to FlexFit.tight for both the Containers which will force them to take the maximum space available to them.
One can see that when the screen size is increased in the horizontal direction the width of the containers in the rows changes to adjust according to the screen size, but the blue container does not change its width as it is a direct child of Column and Flexible widget only allows the change of the size of the child along the main axis of the parent widget which is vertical in case of Column. And when the screen size is changed in the vertical direction we can see that the height of the blue Container changes but other containers are not responsive in this direction as they are a child of the Row widget. 
Example 3: Wrapping the top and bottom Row widgets with Flexible widgets
Dart
import 'package:flutter/material.dart'; void main() {  runApp(MaterialApp(    home: Scaffold(        appBar: AppBar(            title: Text('GeeksforGeeks'),            backgroundColor: Colors.greenAccent[400],            leading: IconButton(              icon: Icon(Icons.menu),              onPressed: () {},              tooltip: 'Menu',            ) //IconButton            ), //AppBar        body: Center(          child: Container(              child: Padding(            padding: const EdgeInsets.all(14.0),            child: Column(              children: <Widget>[                Flexible(                  flex: 1,                  fit: FlexFit.tight,                  child: Row(                    children: <Widget>[                      Flexible(                        flex: 1,                        fit: FlexFit.tight,                        child: Container(                          decoration: BoxDecoration(                            borderRadius: BorderRadius.circular(10),                            color: Colors.red,                          ), //BoxDecoration                        ), //Container                      ), //Flexible                      SizedBox(                        width: 20,                      ), //SizedBox                      Flexible(                        flex: 1,                        fit: FlexFit.tight,                        child: Container(                            decoration: BoxDecoration(                          borderRadius: BorderRadius.circular(10),                          color: Colors.red,                        ) //BoxDecoration                            ), //Container                      ) //Flexible                    ], //<Widget>[]                    mainAxisAlignment: MainAxisAlignment.center,                  ), //Row                ), //Flexible                SizedBox(                  height: 20,                ), //SizedBox                Flexible(                  flex: 1,                  fit: FlexFit.tight,                  child: Container(                    width: 380,                    height: 200,                    decoration: BoxDecoration(                        borderRadius: BorderRadius.circular(10),                        color: Colors.blue), //BoxDecoration                  ), //Container                ), //Flexible                SizedBox(                  height: 20,                ), //SizedBox                Flexible(                  flex: 2,                  fit: FlexFit.tight,                  child: Row(                    children: <Widget>[                      Flexible(                        flex: 2,                        fit: FlexFit.tight,                        child: Container(                          width: 180,                          height: 300,                          decoration: BoxDecoration(                            borderRadius: BorderRadius.circular(10),                            color: Colors.cyan,                          ), //BoxDecoration                        ), //Container                      ), //Flexible                      SizedBox(                        width: 20,                      ), //SizedBox                      Flexible(                        flex: 2,                        fit: FlexFit.tight,                        child: Container(                            width: 180,                            height: 300,                            decoration: BoxDecoration(                              borderRadius: BorderRadius.circular(10),                              color: Colors.cyan,                            ) //BoxDecoration                            ), //Container                      ) //Flexible                    ], //<Widget>[]                    mainAxisAlignment: MainAxisAlignment.center,                  ), //Row                ), //Flexible              ], //<Widget>[]              mainAxisAlignment: MainAxisAlignment.spaceBetween,              crossAxisAlignment: CrossAxisAlignment.center,            ), //Column          ) //Padding              ), //Container        ) //Container        ), //Scaffold     debugShowCheckedModeBanner: false,  )); //MaterialApp}
Output: 
Explanation: Now, in this app, we have wrapped the top and bottom Row widgets with Flexible widgets with each having a flex value of 1. All the fit properties in this app are changes to FlexFit.tight to force child widgets to take all the space available to them. There is also an addition of two SizeBox widgets, one on the top of the blue Container and one below that.
Again taking a look at the app we can see that when screen size changes in the vertical direction the height of all the containers also change according to that, but when screen size changes in the horizontal direction, except the blue container width of all the containers changes also. This is due to the reason the blue Container is just a direct child of the Column widget which allows it to change direction in the only vertical direction. Though we can also make the blue Container responsive by rapping it with a Row widget, which will give it the ability to adjust its size in the horizontal direction as well when wrapped with Flexible,
So, this is how we can make widgets of the whole application responsive in a flutter, by using the Flexible widget.
kalrap615
kapoorsagar226
simranarora5sos
android
Flutter
Flutter-widgets
Dart
Flutter
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Flutter - DropDownButton Widget
Flutter - Custom Bottom Navigation Bar
Flutter - Checkbox Widget
Dart Tutorial
Flutter - BoxShadow Widget
Flutter - DropDownButton Widget
Flutter - Custom Bottom Navigation Bar
Flutter Tutorial
Flutter - Checkbox Widget
Flutter - BoxShadow Widget