Widgets 15 | Stack

In this tutorial, you will learn how to use the Stack in the flutter.

Before Stack

Before our tutorial, we should create a page to contain our code.

import "package:flutter/material.dart";
import 'package:flutter_widgets/const/_const.dart';

class StackPage extends StatefulWidget {
  @override
  _StackState createState() => _StackState();
}

class _StackState extends State<StackPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(PageName.STACK),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            //our code.
            SizedBox(height: 600)
          ],
        ),
      ),
    );
  }
}

It just shows an empty page with a title.

Simple Use

The Stack is a layout that can contain multiple children widgets, but they are in different layers. Let's look at an example.

 Widget _simpleStack() => Container(
        constraints: BoxConstraints.expand(height: 160),
        child: Stack(
          children: <Widget>[
            Container(
              color: RED,
            ),
            Container(
              margin: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
              color: BLUE_LIGHT,
            ),
            Container(
              margin: EdgeInsets.symmetric(vertical: 30, horizontal: 60),
              color: PURPLE,
            ),
            Container(
              margin: EdgeInsets.symmetric(vertical: 50, horizontal: 80),
              color: TEXT_BLACK_LIGHT,
            ),
          ],
        ),
      );

It shows as below, you can see the layers all in the same position but different size. The upper layer just put upon the bottom one, just like a book with different pages put on a table.

Constructor

So, let's look at its constructor.

Stack({
    Key key,
    this.alignment = AlignmentDirectional.topStart,
    this.textDirection,
    this.fit = StackFit.loose,
    this.overflow = Overflow.clip,
    List<Widget> children = const <Widget>[],
  })

The parameters are a bit less for us. But should tell you how to use them.

alignment

We have used the alignment in the Container. It is the same as the alignment in the Container. You can find more detail in the Widgets 01 | Container. I just give an example here to describe it here.

 Widget _alignStack() => Container(
        margin: EdgeInsets.only(top: 10),
        color: BLUE_DEEP,
        constraints: BoxConstraints.expand(height: 160),
        child: Stack(
          alignment: Alignment.centerRight,
          children: <Widget>[
            Container(
              height: 100,
              width: 100,
              color: Colors.white,
            ),
            Container(
              height: 60,
              width: 60,
              color: TEXT_BLACK_LIGHT,
            ),
          ],
        ),
      );

It shows as follows.

textDirection

This will control the direction of the Text. It has two choices, the ltr draws from left to right, the rtl draws it from right to left.

Widget _textLeftStack() => Container(
        margin: EdgeInsets.only(top: 10),
        color: GREEN,
        padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
        constraints: BoxConstraints.expand(height: 60),
        child: Stack(
          textDirection: TextDirection.ltr,
          children: <Widget>[
            Text(
              "Flutter Open drawed from left to rigt",
              style: TextStyle(color: TEXT_BLACK_LIGHT),
            )
          ],
        ),
      );

  Widget _textRightStack() => Container(
        margin: EdgeInsets.only(top: 10),
        color: PURPLE,
        padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
        constraints: BoxConstraints.expand(height: 60),
        child: Stack(
          textDirection: TextDirection.rtl,
          children: <Widget>[
            Text(
              "Flutter Open drawed from right to left",
              style: TextStyle(color: TEXT_BLACK_LIGHT),
            )
          ],
        ),
      );

It will show you as below.

fit

This will control the size of the children widgets in the flutter.It has only three types of the StackFit.

Widget _fitStack() => Container(
      color: PURPLE,
      margin: EdgeInsets.only(top: 10),
      constraints: BoxConstraints.expand(height: 220),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Container(
            constraints: BoxConstraints.expand(height: 60),
            color: RED,
            child: Stack(
              fit: StackFit.loose,
              children: <Widget>[
                Container(
                  color: BLUE_DEEP,
                  child: Text(
                    "StackFit.loose",
                    style: TextStyle(color: TEXT_BLACK_LIGHT, fontSize: 20),
                  ),
                )
              ],
            ),
          ),
          Container(
            constraints: BoxConstraints.expand(height: 60),
            color: GREEN,
            child: Stack(
              fit: StackFit.expand,
              children: <Widget>[
                Container(
                  child: Text(
                    "StackFit.expand",
                    style: TextStyle(color: TEXT_BLACK_LIGHT, fontSize: 20),
                  ),
                  color: BLUE_LIGHT,
                )
              ],
            ),
          ),
          SizedBox(height: 10),
          Container(
            constraints: BoxConstraints.expand(height: 60),
            color: RED_LIGHT,
            child: Stack(
              fit: StackFit.passthrough,
              children: <Widget>[
                Container(
                  child: Text(
                    "StackFit.passthrough",
                    style: TextStyle(color: TEXT_BLACK_LIGHT, fontSize: 20),
                  ),
                  color: GREEN,
                )
              ],
            ),
          )
        ],
      ));

It will show you as follows.The loose make the children widget as small as possible, the expand set the children as large as possible. The passthrough will depend on its parent widget.

overflow

This parameter will control the children widget. When its content outside the Stack. whether the children widget will be visible or clip. Let's look at an example.

 Widget _overVisibleStack() => Container(
    margin: EdgeInsets.only(top: 10),
    color: BLUE_LIGHT,
    constraints: BoxConstraints.expand(height: 40),
    child: Stack(
      overflow: Overflow.visible,
      children: <Widget>[
        Positioned(
          top: 15,
          child: Text(
            "Flutter Open is too long to draw here, it will be visible.\n666666666666666666666666666666666",
            style: TextStyle(color: TEXT_BLACK_LIGHT),
          ),
        )
      ],
    ),
  );
  Widget _overClipStack() => Container(
        margin: EdgeInsets.only(top: 10),
        color: BLUE_LIGHT,
        constraints: BoxConstraints.expand(height: 40),
        child: Stack(
          overflow: Overflow.clip,
          children: <Widget>[
            Positioned(
              top: 15,
              child: Text(
                "Flutter Open is too long to draw here, it will be cliped.\n666666666666666666666666666666666",
                style: TextStyle(color: TEXT_BLACK_LIGHT),
              ),
            )
          ],
        ),
      );

It will show you like this. The first one shows the contents, but two cut the part that outside the Stack.

Positioned

It isn't the parameter of the Stack, but it relates to the Stack. It will help you locate the children widgets in the Stack. Let's look at its constructor.

const Positioned({
    Key key,
    this.left,
    this.top,
    this.right,
    this.bottom,
    this.width,
    this.height,
    @required Widget child,
  }) 

The parameters, left, top, right, and bottom will control the distance inside the Stack. If we set left: 10, this Positioned will locate at the position at the Stack that the distance from the left of the Stack is 10. Let's look at an example.

Widget _posStack() => Container(
        margin: EdgeInsets.only(top: 10),
        color: TEXT_BLACK_LIGHT,
        constraints: BoxConstraints.expand(height: 100),
        child: Stack(
          children: <Widget>[
            Positioned(
              left: 10,
              top: 10,
              height: 60,
              width: 60,
              child: Container(
                color: RED,
              ),
            ),
            Positioned(
              right: 200,
              top: 30,
              height: 60,
              width: 60,
              child: Container(
                color: BLUE_DEEP,
              ),
            ),
            Positioned(
              right: 10,
              top: 10,
              height: 60,
              width: 60,
              child: Container(
                color: GREEN,
              ),
            ),

          ],
        ),
      );

It will show you as follows.

Conclusion

The Stack is very common in the flutter. If you have a layout that doesn't have a simple direction, such as horizontal, vertical. You can consider this layout.

Thanks for your reading!

The end.

Whole code in GitHub,star to support.

Facebook Page

Twitter

GitHub

Medium

Last updated