Flutter Widgets (Stack & Positioned) The Whole Picture.

Murtaza Sulaihi
Flutter Community

--

This is my 5th article on Medium and 5 is a recurring number, every time you multiple 5 by 5 and then again with 5, the number 5 always stays, endlessly. It is consistent so would I like to be and I am trying to do so. I just need a little help from you readers to read what I write and tell me how I am doing by leaving a few comments and suggestions.

So what are we going to talk about today? We will be discussing the Stack widget, along with the Positioned widget because Stack needs Positioned widget to position its children on its vertical and horizontal axis. With the Positioned widget, it becomes really easy to arrange children inside the Stack. Which in return creates beautiful UI.

Introduction

Stack widget stacks its children on top of each other like a stack of books, now you can re-arrange that stack however you want. You can add colour and shape using the Container widget and give a background to your UI and have a Card widget on top of it, there are so many possibilities as per your imagination.

left: normal Stack right: Stack + Positioned

These are the parameters of a Stack widget.

Stack(
alignment: Alignment.center,
textDirection: TextDirection.rtl,
fit: StackFit.loose,
overflow: Overflow.visible,
clipBehavior: Clip.hardEdge,
children: <Widget>[]
),

And these are the parameters of a Positioned widget.

Positioned(
height: 0,
width: 0,
left: 0,
right: 0,
top: 0,
bottom: 0,
child: (),
)

If you refer to the image above, the left image is a normal Stack widget with 3 containers as its children inside it with center alignment. The image on the right is the same but with Positioned widget inside the Stack wrapping Container 2 and Container 3 in it. Alignment property and Text Direction property has been discussed in detail in my previous article on Row, Column and Flex, Other than those two properties fit and overflow are the important ones used for arranging the children inside the Stack.

There are 3 options for fit property.
1) fit: StackFit.loose,
2) fit: StackFit.expand,
3) fit: StackFit.passthrough,

The first one stackFit.loose allows the constraint to be loosened by its parent. What it basically means if the parent has width and height of around 300x600 pixels, Stack will allow it's all non-positioned children to have a width or a height from zero to 300 and zero to 600 respectively. Pretty much similar to the images above.

Now on the other hand stackFit.expand will tighten the constraints to the biggest sized allowed. For example, if the width and the height of the parent are 100x600 pixels, then all non-positioned children will be forced to have the same width and height. Please refer to the image below.

stackFit.expand

In the above image Container 1 is not wrapped inside a Positioned widget, whereas Container 2 and 3 are, so when stackFit.expand is used Container 1 expands to the width and the height of the parent.

Now stackFit.passthrough is little complicated, if you want to see the difference between this property from the other two, you will need to wrap Stack widget with an Expanded widget inside a Row widget. Since Row places its widgets horizontally, the horizontal constraints will be tight, it means it will pass through and fill the space horizontally and vertically the constraints will be loose. Check the code and image below to better understand it.

Row(
children: [
Expanded(
child: Stack(
fit: StackFit.passthrough,
overflow: Overflow.visible,
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.red,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 10.0,
spreadRadius: 3.0,
offset: Offset(10.0, 10.0),
),
],
),
alignment: Alignment.centerRight,
width: 200,
height: 200,
child: RotatedBox(
quarterTurns: 1,
child: Text(
'Container 1',
style:
TextStyle(fontSize: 18.0, color: Colors.white),
),
),
),
stackFit.passthrough

Now let us discuss the other important property which you might have already observed in the above image, how container 2 is outside the bounds of the red container.

that is … OverFlow

OverFlow property has 2 options
overflow: Overflow.visible,
overflow: Overflow.clip,

In the above image, the red and green container has overFlow.visible, since it is wrapped inside a Positioned widget, we still have to discuss the Positioned widget I know and we will in just a bit, overflow as the named suggest the green container is overflowing outside the bounds of the red container. Now if we use overflow.clip, then the result will the purple and amber container, the amber container is clipped and sized according to the size of the purple container.

Positioned Widget

Now the parameters or the properties of the Stack widget works really well if the children inside the Stack is wrapped with Positioned widget. We have already seen all the parameters of the Positioned widget, let us understand it now and how well it works with the Stack.

The top, bottom and height property changes the position of the widget on the vertical axis and left-right and width property changes the position of the widget on the horizontal axis.

tip to Remember : that only two properties can be used at a time from horizontal values and only two from vertical values. You cannot use all the 3 together, you can use any two in any combination. Now another important thing to remember is that the width and height values of the Positioned widget will override the values of the child widget wrapped inside it.

Stack(
overflow: Overflow.visible,
children: [
Container(
decoration: BoxDecoration(
color: Colors.red,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 10.0,
spreadRadius: 3.0,
offset: Offset(10.0, 10.0),
),
],
),
alignment: Alignment.centerRight,
width: 300,
height: 300,
child: RotatedBox(
quarterTurns: 1,
child: Text(
'Container 1',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
),
),
Container(
decoration: BoxDecoration(
color: Colors.red,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 10.0,
spreadRadius: 3.0,
offset: Offset(10.0, 10.0),
),
],
),
alignment: Alignment.centerRight,
width: 300,
height: 300,
child: RotatedBox(
quarterTurns: 1,
child: Text(
'Container 1',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
),
),
Positioned(
left: -15,
top: -15,
child: Container(
decoration: BoxDecoration(
color: Colors.green,
boxShadow: [
BoxShadow(
color: Colors.black54,
blurRadius: 15.0,
spreadRadius: 3.0,
offset: Offset(10.0, 10.0),
),
],
),
alignment: Alignment.bottomCenter,
width: 250,
height: 250,
child: Text(
'Container 2',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
),
),
Positioned(
top: -50,
right: 30,
child: Container(
decoration: BoxDecoration(
color: Colors.blue,
boxShadow: [
BoxShadow(
color: Colors.black54,
blurRadius: 10.0,
spreadRadius: 2.0,
offset: Offset(5.0, 5.0),
),
],
),
alignment: Alignment.center,
width: 200,
height: 200,
child: Text(
'Container 3',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
),
),
],
),
Positioned Widget.

Please go through the above code along with the above image, I have wrapped the green and blue container inside a Positioned widget and have given different values for its horizontal and vertical values which eventually results in the above image. I think its really cool, giving a bit of a 3D kind of an effect to it. As I said earlier lots can be done using the Stack and Positioned widget for creating great background and UI for flutter applications. You just to need to try it out and experiment with it.

That’s all for this story and do check out my other stories leaving the links below. Please leave your valuable comments, share this story with your friends and family who you might think benefit from it, clap for me as many times possible, You can always support by buying a Cup of Coffee ☕️ for me if you think you have learned someting new. Thank you !

Links to my previous stories.

  1. SafeArea Widget
  2. Expanded & Flexible Widget
  3. Container Widget
  4. Row, Column & Flex Widget
https://www.twitter.com/FlutterComm

--

--

Responses (1)