Open In App

Flutter – Stack Widget

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Stack widget is a built-in widget in flutter SDK which allows us to make a layer of widgets by putting them on top of each other. Many of the times a simple row and column layout is not enough, we need a way to overlay one widget on top of the other, for example, we might want to show some text over an image, so to tackle such a situation we have Stack widget. The Stack widget has two types of child one is positioned which are wrapped in the Positioned widget and the other one is nonpositioned which is not wrapped in the Positioned widget. For all the non-positioned widgets the alignment property is set to the top-left corner. The positioned child widgets are positioned through the top, right, left, and bottom properties. The child widgets are of Stack are printed in order the top-most widget becomes the bottom-most on the screen and vice-versa. We can use the key property of the Stack widget to change that order or to assign a different order. 

Constructor of Stack Class:

Stack(
{Key key,
AlignmentGeometry alignment: AlignmentDirectional.topStart,
TextDirection textDirection,
StackFit fit: StackFit.loose,
Overflow overflow: Overflow.clip,
Clip clipBehavior: Clip.hardEdge,
List<Widget> children: const <Widget>[]}
)

Properties of Stack Widget:

  • alignment: This property takes a parameter of Alignment Geometry, and controls how a child widget which is non-positioned or partially-positioned will be aligned in the Stack.
  • clipBehaviour: This property decided whether the content will be clipped or not.
  • fit: This property decided how the non-positioned children in the Stack will fill the space available to it.
  • overflow: This property controls whether the overflow part of the content will be visible or not,
  • textDirection: With this property, we can choose the text direction from right to left. or left to right.

Example 1:

Dart




import 'package:flutter/material.dart';
 
void main() {
  runApp(MaterialApp(
          home: Scaffold(
              appBar: AppBar(
                title: Text('GeeksforGeeks'),
                backgroundColor: Colors.greenAccent[400],
              ), //AppBar
              body: Center(
                child: SizedBox(
                  width: 300,
                  height: 300,
                  child: Center(
                    child: Stack(
                      children: <Widget>[
                        Container(
                          width: 300,
                          height: 300,
                          color: Colors.red,
                        ), //Container
                        Container(
                          width: 250,
                          height: 250,
                          color: Colors.black,
                        ), //Container
                        Container(
                          height: 200,
                          width: 200,
                          color: Colors.purple,
                        ), //Container
                      ], //<Widget>[]
                    ), //Stack
                  ), //Center
                ), //SizedBox
              ) //Center
              ) //Scaffold
          ) //MaterialApp
      );
}


Output:

stack widget

Explanation: Taking a look at the code of this flutter app, we can see that the parent widget for this app is Scaffold. On the top of the widget tree, we have AppBar widget with title Text widget reading ‘GeeksforGeeks‘ and the background color of the app bar is greenAccent[400]. In the body of the app, the parent widget is Center followed by the SizedBox of height 300 and width 300. SizedBox is also having a child Center which in turn is holding the Stack widget. In the Stack widget, we have a list of children widgets holding three Container widgets. The first Container widget is having a height and width of 300, the same as the SizedBox, with a red color. The Second Container is having a width and height of 250 with black color. The third Container is having a width and height of 200 with a purple color. Now, looking at the app we can see that all three containers that are children to Stack are stacked on top of each other with the red containers at the bottom of the purple at the top, and the black in the middle. All these three containers are non-positioned widget in Stack so the alignment property for them is set to Alignment.topRight, therefore we can see all of them aligned to the top right corner.

Example 2:

Dart




import 'package:flutter/material.dart';
 
void main() {
  runApp(MaterialApp(
          home: Scaffold(
              appBar: AppBar(
                title: Text('GeeksforGeeks'),
                backgroundColor: Colors.greenAccent[400],
              ), //AppBar
              body: Center(
                child: SizedBox(
                  width: 300,
                  height: 300,
                  child: Center(
                    child: Stack(
                      children: <Widget>[
                        Container(
                          width: 300,
                          height: 300,
                          color: Colors.red,
                          padding: EdgeInsets.all(15.0),
                          alignment: Alignment.topRight,
                          child: Text(
                            'One',
                            style: TextStyle(color: Colors.white),
                          ), //Text
                        ), //Container
                        Container(
                          width: 250,
                          height: 250,
                          color: Colors.black,
                          padding: EdgeInsets.all(15.0),
                          alignment: Alignment.bottomLeft,
                          child: Text(
                            'Two',
                            style: TextStyle(color: Colors.white),
                          ), //Text
                        ), //Container
                        Container(
                          height: 200,
                          width: 200,
                          padding: EdgeInsets.all(15.0),
                          alignment: Alignment.bottomCenter,
                          decoration: BoxDecoration(
                            image: DecorationImage(
                                image: NetworkImage(
                                    "https://pbs.twimg.com/profile_images/1304985167476523008/QNHrwL2q_400x400.jpg") //NetworkImage
                                ), //DecorationImage
                          ), //BoxDecoration
                          child: Text(
                            "GeeksforGeeks",
                            style:
                                TextStyle(color: Colors.white, fontSize: 20.0),
                          ), //Text
                        ), //Container
                      ], //<Widget>[]
                    ), //Stack
                  ), //Center
                ), //SizedBox
              ) //Center
              ) //Scaffold
          ) //MaterialApp
      );
}


Output:

stack widget

Explanation: In this app, we have added padding and a child Text widget is each of the containers with the text color being white. In the first Container, the text is ‘One’, and the alignment is set to Alignment.topRight, which puts the Text widget in the top-right corner. In the second Container, the text is ‘Two’, and the alignment is set to Alignment.bottom left, which put the child which is the Text in the bottom-left corner. In the third Container, we have added a background image showing the GeeksforGeeks logo by using the decoration property in the container. The text in this container is ‘GeeksforGeeks’ and the alignment is set to bottom-center, which puts the test above the image in the bottom Centre part of the container. 

This is how we can use the Stack widget to show the text (or any other widget) on top of another widget.

Example 3:

Dart




import 'package:flutter/material.dart';
 
void main() {
  runApp(MaterialApp(
          home: Scaffold(
              appBar: AppBar(
                title: Text('GeeksforGeeks'),
                backgroundColor: Colors.greenAccent[400],
              ), //AppBar
              body: Center(
                child: SizedBox(
                  width: 300,
                  height: 300,
                  child: Center(
                    child: Stack(
                      fit: StackFit.expand,
                      clipBehavior: Clip.antiAliasWithSaveLayer,
                      overflow: Overflow.visible,
                      children: <Widget>[
                        Container(
                          width: 300,
                          height: 300,
                          color: Colors.red,
                        ), //Container
                        Positioned(
                          top: 80,
                          left: 80,
                          child: Container(
                            width: 250,
                            height: 250,
                            color: Colors.black,
                          ),
                        ), //Container
                        Positioned(
                          left: 20,
                          top: 20,
                          child: Container(
                            height: 200,
                            width: 200,
                            color: Colors.purple,
                          ),
                        ), //Container
                      ], //<Widget>[]
                    ), //Stack
                  ), //Center
                ), //SizedBox
              ) //Center
              ) //Scaffold
          ) //MaterialApp
      );
}


Output:

stack widget

Explanation: In this app, we have wrapped the purple and the black Container with a Positioned widget, so these children widgets are now positioned widgets. In the Stack widget, the fit property is set to StackFit.expand which will force all its children widgets to take maximum space available to them. The clip property is set to antiAliasWithSaveLayer, which avoid any bleeding edges. And the overflow is set to visible, to make the overflowing parts visible. Now, that we have wrapped containers with the Positioned widget we need to specify their position. For the black Container, the top and the left properties are set to 80 each, which makes it overflow out of the SizedBox and the red Container. But as the overflow is set to visible, so we are able to see the overflowing portion of the black Container. And for the purple Container, the top and left are set to 20 each, which makes it a bit offset when compared to the first example.

So, this is how the Stack widget can be used. But we can also achieve a similar or same result with CustomSingleChildLayout widget and CustomMultiChildLayout widget.



Last Updated : 21 Feb, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads