Flutter Widgets (Boxes Part-1) The Whole Picture.

Murtaza Sulaihi
Flutter Community
7 min readOct 3, 2020

--

We are going to talk about boxes today. Real use case of a box, a box is used for storage, for safekeeping, to organize, to move items from one place to another, children use boxes to show their creativity and people use a stack of boxes to climb also.

In the world of programming, a box is used as an analogy to explain variables. While I was learning JAVA this is how it was explained to me. A box itself is a variable data type. Then you need to name the box, which is the name of the variable. And when we put something inside the box which is the value of the variable.

There are 10 different types of Box Widgets in Flutter.

  1. Constrained Box
  2. Decorated Box + Transition
  3. Fitted Box
  4. Fractionally Sized Box
  5. Limited Box
  6. Overflow Box
  7. Place Holders
  8. Rotated Box
  9. Sized Box
  10. Sized Overflow Box

I am not going to write 10 different articles on each widget, instead, I am going to combine it and write in two parts. So for the first part of this article, I am going to discuss Constrained Box, Fractionally Sized Box, Overflow Box, Sized Box, Sized Overflow Box.

Constrained Box

A Constrained box additionally imposes width and height constraints on its child. A Sized box or a Container only has width and height property, with Constrained Box you can add properties like minimum and maximum values to the existing width and height. Constrained Box takes in a single required property of BoxConstraints which allows you to define the minimum and maximum values of width and height.

--------------------- Constrained Box constructor -----------------
ConstrainedBox(
constraints: BoxConstraints( // @required
maxHeight: 75, // max height to satisfy the constraints
minHeight: 0.0, // min height to satisfy the constraints
maxWidth: 200, // max width to satisfy the constraints
minWidth: 0.0, // min width to satisfy the constraints

),
The values must satisfy following rules:
1) 0.0 <= minWidth <= maxWidth <= double.infinity
2) 0.0 <= minHeight <= maxHeight <= double.infinity

Now let’s look at an example, how a Constrained Box is used.

ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 75,
minHeight: 0.0,
maxWidth: 200,
minWidth: 0.0,
),

child: Container(
alignment: Alignment.center,
height: 100,
width: 300,

color: Colors.brown,
child: Text(
'This is a Constrained Box',
style: TextStyle(fontSize: 20, color: Colors.white),
),
),
),

If you look closely at the code and the image on the left representing the above code, you will notice that the Container has a fixed width and height, but it is wrapped inside a Constrained box. The maximum height and the maximum width of the Constrained box are lesser than the Container, so it overrides it and the Container is smaller than its original width and height.

tip: Constrained box needs to be a parent widget for its Constraints to be enforced on its child.

Additionally, BoxConstraints has five different types.

1) BoxConstraints.tight(Size size)
2) BoxConstraints.tightFor({double width,double height,})
3) BoxConstraints.tightForFinite({double width = double.infinity,
double height = double.infinity,})
4) BoxConstraints.loose(Size size)
5) BoxConstraints.expand({double width, double height,})

Sized Box

This flutter widget is used for sizing of its child widget. Unlike the Container widget, Sized Box does not have colour or decoration property. None of its parameters is required when using it because it can be used to create a space between widgets by adding either width, height or both. The constructor is pretty basic as mentioned below.

SizedBox(
width: 0.0,
height: 0.0,
child: Text('Sized Box Widget'),
),

One thing you need to understand is that the width and the height of Sized Box are for its child, it sizing its child but not itself. If you give just width and height without the child it will just create a space, but if you add a child, it will give the width and height to that child. To understand better look at the image below, see how the width and height property changes the child widget accordingly.

The above image explains a lot, if you give width and height the child widget will be sized to it, else if you don’t the Sized Box will size itself according to the size of the child, in the above case the Text widget, try increasing the font size of the text and the Sized Box will also increase its width and height.

Additionally, SizedBox has 3 different types.

// Creates a box that will become as large as its parent allows.
const SizedBox.expand({ Key key, Widget child })
// Creates a box that will become as small as its parent allows.
const SizedBox.shrink({ Key key, Widget child })
// Creates a box with the specified size.
SizedBox.fromSize({ Key key, Widget child, Size size })

Fractionally Sized Box

--------------------- constructor ---------------------
FractionallySizedBox(
widthFactor: 0.6, // this means 60% width
heightFactor: 0.3, // this means 30% height
alignment: Alignment.center, // default is center
child: RaisedButton()
),

If you want to size your widget relative to the size available in the parent widget then use FractionallySizedBox. You need not mention exact width or height instead you mention the size infractions and it will size it according to space available in the parent widget. For example, if you want the height of the button to be 60% and width to be 30% of the available size, then the code will look something like this. Here the FractionallySizedBox is wrapped inside a Container sized 300x300 and a RaisedButton is wrapped inside a FractionallySizedBox, this is how it will look like.

Container(
width: 300,
height: 300,
color: Colors.brown,
child: FractionallySizedBox(
widthFactor: 0.6,
heightFactor: 0.3,

child: RaisedButton(
onPressed: () {},
color: Colors.amber,
child: Text(
'Raised Button',
style: TextStyle(fontSize: 22),
),
),
),
),

The button takes up 60% width of the Container and 30% height of the Container, if you increase the size of the Container, the size of the button will also increase automatically sizing itself relatively to the size of the Container according to the width and height factor mentioned in the FractionallySizedBox.

SizedOverFlow Box & OverFlow Box

Both these widgets are pretty similar but with a slight difference. The SizedOverFlow box has a specific size but it does not override the size of the parent, rather it sizes its parent widget and lets its child widget overflow the constraints. On the other hand, OverFlow Box imposes its size on its child widget and lets its child overflow outside the boundaries of the parent. Depending on the design of your UI either of them can be used.

tip: Try using both inside a Container widget to give color and other decoration properties to it, because without it you will not see any difference in the UI.

let us look the at constructor first and little code how as to how to play around with it little…

-------------------- SizedOverflowBox constructor ----------------
SizedOverflowBox(
size: Size(50, 150), // takes up Size(width, height) widget
alignment: Alignment.center, // default is center
child: RaisedButton()
),
---------------------- OverflowBox constructor --------------------
OverflowBox(
maxHeight: 300, // max height constraint to give the child
maxWidth: 300, // max width constraint to give the child
minHeight: 50, // minimum height constraint to give the child
minWidth: 50, // minimum width constraint to give the child
alignment: Alignment.center, // default is center
child: SizedBox()
),

SizedOverflow Box code and image

SizedOverFlow Box image
Container(
color: Colors.brown,
child: SizedOverflowBox(
size: Size(50, 150),
alignment: Alignment.center,

child: RaisedButton(
onPressed: () {},
color: Colors.amber,
child: Text(
'Raised Button',
style: TextStyle(fontSize: 22),
),
),
),
),

The size mentioned inside the SizedOverflow box is for the Container, and the Button widget is overflowing its bounds.

OverFlow box code and image.

Container(
width: 200,
height: 100,
decoration: BoxDecoration(
border: Border.all(color: Colors.purple, width: 5.0),
),
child: OverflowBox(
maxHeight: 300,
maxWidth: 300,
minHeight: 50,
minWidth: 50,
alignment: Alignment.center,

child: SizedBox(
height: 275,
width: 0,
child: RaisedButton(
onPressed:(){},
color: Colors.amber,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: []
),

I haven’t posted the entire code, the Column widget consist of around 12 Text widgets to create something like above, but for the sake of explanation, I programmed it in that way. The size of the Container widget does not affect the SizedBox or the Raised button, those two are controlled by the OverFlow box and based on its parameters you can adjust the height and width of the SizedBox. And as the name suggest Button widget overflows outside the boundaries of the Container.

Well, we have come to the end of our story, stay tuned for the 2nd part of this story next week. Till then stay safe and keep experimenting because as I always say Discovery requires Experimentation”.

Don’t forget to share my story with your friends and family and clap for me if you have learned something new. Thank you!

Care to follow me … on Instagram, Twitter, Linkedin, Reddit.

You can always support by buying a Cup of Coffee ☕️ for me.

https://www.twitter.com/FlutterComm

--

--

Murtaza Sulaihi
Flutter Community

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