Open In App

Flutter – Stack Widget

Last Updated : 18 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

The Stack widget in Flutter is a powerful tool that allows for the layering of multiple widgets on top of each other. While layouts like Row and Column arrange widgets horizontally and vertically, respectively, Stack provides a solution when you need to overlay widgets. For instance, if you want to display text over an image, the Stack widget is ideal for such scenarios.

The Stack widget has two types of child widgets:

  • Positioned widgets: These are wrapped in the Positioned widget and are positioned using the top, right, left, and bottom properties, allowing for precise control of their placement within the stack.
  • Non-positioned widgets: These are simply placed in the Stack without being wrapped in a Positioned widget. By default, they are aligned to the top-left corner unless you specify a different alignment using the alignment property.

Stack layers its children in the order they are declared, meaning the first widget appears at the bottom and the last one on top. You can use the key property to modify this rendering order or assign a specific order to the child widgets if needed.

Constructor of Stack Class:

Syntax
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 of the above Program:

In this Flutter app, the root widget is the Scaffold, which provides the basic structure. At the top of the widget tree, there’s an AppBar with a Text widget displaying “GeeksforGeeks” as the title, and the background color of the AppBar is set to Colors.greenAccent[400].

In the body of the app, the parent widget is Center, which centers its child widget—a SizedBox with a height and width of 300. The SizedBox itself contains another Center widget, which holds the Stack widget.

Inside the Stack, there are three Container widgets:

  1. The first Container has a width and height of 300 (matching the SizedBox) and is colored red.
  2. The second Container has a width and height of 250 and is colored black.
  3. The third Container is 200×200 in size and is colored purple.

When we run the app, we can see that these three containers are stacked on top of each other, with the red container at the bottom, the black container in the middle, and the purple container on top. Since all three containers are non-positioned widgets within the Stack, their default alignment is set to Alignment.topRight, causing them to be 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 of the above Program:

In this app, we’ve added padding and a Text widget to each of the three containers, with the text color set to white.

  • In the first Container, the text is “One,” and the alignment is set to Alignment.topRight, placing the text in the top-right corner.
  • In the second Container, the text is “Two,” and the alignment is set to Alignment.bottomLeft, positioning the text in the bottom-left corner.
  • In the third Container, we’ve added a background image displaying the GeeksforGeeks logo by using the decoration property. The text in this container is “GeeksforGeeks,” and its alignment is set to Alignment.bottomCenter, placing the text at the bottom-center, just above the image.

This demonstrates how the Stack widget can be effectively used to overlay text (or any other widget) on top of another widget, allowing for flexible and layered UI designs.

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 of the above Program:

In this app, we’ve wrapped the purple and black Container widgets inside Positioned widgets, making them positioned children within the Stack.

The Stack widget’s fit property is set to StackFit.expand, which forces all its child widgets to take up the maximum available space. The clipBehavior is set to Clip.antiAliasWithSaveLayer to prevent any bleeding edges, ensuring smooth edges around the child widgets. Additionally, the overflow is set to visible, allowing any part of the child widgets that exceed their boundaries to remain visible.

Since the purple and black containers are wrapped with Positioned, we now need to specify their positions.

  • For the black Container, the top and left properties are both set to 80, which causes it to overflow beyond the SizedBox and the red container underneath. However, due to the overflow being set to visible, we can still see the overflowing portion.
  • For the purple Container, the top and left are both set to 20, making it slightly offset compared to the original example.


This shows how we can use the Stack widget to create flexible layouts with overlapping and positioned elements. However, similar layouts can also be achieved using widgets like CustomSingleChildLayout or CustomMultiChildLayout, which provide even more control over custom positioning.



Next Article

Similar Reads