Introduction

For the application of modern APP, in order to be more beautiful, it is usually necessary to use the stacking effect of different images, such as adding a button on the background avatar of an APP user, indicating that user information can be modified.

To achieve this effect, we need to stack other widget objects on top of an Image. Flutter provides us with such a very convenient layout component called Stack. Today, let's talk about the use of Stack.

Detailed explanation of Stack

Let's first look at the definition of Stack:

 class Stack extends MultiChildRenderObjectWidget

Stack inherits from MultiChildRenderObjectWidget, which means that multiple child widget objects can be rendered in the stack.

Because the child in the Stack is an overlapping relationship, the child needs to be positioned. According to the positioning, the child in the Stack can be divided into two types, namely positioned and non-positioned.

The so-called positioned means that the child widget is wrapped in Positioned. What is Positioned?

Positioned is a widget specially used to locate the child position in the Stack. Therefore, Positioned must be used in Stack, and only two widgets, StatelessWidget or StatefulWidget, can exist between the paths of Positioned and Stack.

If an object is contained in Positioned, then the object is a Positioned object in a Stack.

In addition to the encapsulated child, there are 6 properties in Positioned, as follows:

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

The six properties are left, top, right, bottom, width and height. Among them, left, top, right, bottom represent the distance to the left, top, right, and bottom respectively, and this distance is relative to the stack. The width and height represent the width and height of Positioned.

In fact, use left and right to define width, and use top and bottom to define height.

If none of the three values in one axis exist, then Stack.alignment is used to position the child elements.

If none of the six values exist, then the child is a non-positioned child.

For non-positioned children, it is laid out through the alignment of the Stack, and by default it is laid out according to the top left corners.

Properties of Stack

Let's take a look at what properties are in Stack next. Here is the constructor of Stack:

 Stack({
    Key? key,
    this.alignment = AlignmentDirectional.topStart,
    this.textDirection,
    this.fit = StackFit.loose,
    @Deprecated(
      'Use clipBehavior instead. See the migration guide in flutter.dev/go/clip-behavior. '
      'This feature was deprecated after v1.22.0-12.0.pre.',
    )
    this.overflow = Overflow.clip,
    this.clipBehavior = Clip.hardEdge,
    List<Widget> children = const <Widget>[],
  })

You can see that there are alignment, textDirection, fit, overflow and clipBehavior properties in Stack.

First look at alignment, where alignment is an AlignmentGeometry object, which is mainly used to lay out non-positioned children.

There are two properties in AlignmentGeometry that need to be set, namely start and y.

Start represents the horizontal line positioning range, and its value is strange, -1 represents the edge position of the start side, and 1 represents the edge position of the end side. If the value exceeds this range, it means that the corresponding position exceeds the edge position.

The position of start is associated with TextDirection. If the value of TextDirection is ltr, that is to say, it is arranged from left to right, then start is on the leftmost side. If the value of TextDirection is rtl, that is to say, it is arranged from right to left, then start is on the far right.

If there is a horizontal position, there is a vertical position. This vertical position is represented by y. Its normal value range is also -1 to 1. Of course, you can also exceed this range.

For users to use AlignmentGeometry more conveniently, AlignmentGeometry provides some convenient methods, such as topStart, topCenter, topEnd, etc., you can choose by yourself.

The next property is textDirection, textDirection is a TextDirection object, it has two values, rtl and ltr, when explaining alignment, we have already mentioned textDirection, it will affect the horizontal layout in alignment.

Next is the fit property of the StackFit type. StackFit has three values, loose, expand and passthrough.

loose means a loose structure. For example, the size specified by Stack is 300x500, then the width of its child can be from 0-300, and the height of child can be from 0-500.

Expand means that it is an expansion effect. For example, the size specified by Stack is 300x500, then the width of its child is 300, and the height of the child is 500.

Passthrough means that the limit passed to the stack will be passed to its child as is, without any modification.

overflow indicates whether the children beyond the display part will be clipped. However, this property is already Deprecated, and flutter recommends that we use the clipBehavior property instead.

clipBehavior is a Clip object whose default value is Clip.hardEdge. Several other values are none, hardEdge, antiAlias and antiAliasWithSaveLayer.

none means no clipping, hardEdge has the fastest clipping speed, but the accuracy is not high. antiAlias is a bit slower than hardEdge, but has smooth edges. antiAliasWithSaveLayer is the slowest and should be rarely used.

Use of Stack

With the above explanation, let's take a look at the specific use of Stack.

In our example, we set a background image in the Stack and then overlay a text on the image.

So how should it be implemented?

First, we need to set the alignment of the Stack. We want the center of the text and the image to coincide, that is, to place the text in the middle of the image. We set the alignment of the Stack to Alignment.center.

Next is a background image. Because the original image is a square image, we need to crop the image into a circle. Here we use a very convenient class CircleAvatar to create a circular icon:

 const CircleAvatar(
          backgroundImage: AssetImage('images/head.jpg'),
          radius: 100,
        ),

The above code is able to create a circle with a radius of 100.

Then there is the creation of the text. You can set the text content and the corresponding style to the Text:

 Text(
            '编辑',
            style: TextStyle(
              fontSize: 20,
              fontWeight: FontWeight.bold,
              color: Colors.white,
            ),
          )

Then wrap the Text in a Container and use BoxDecoration to assign a background to it:

 Container(
          decoration: const BoxDecoration(
            color: Colors.green,
          ),
          child: const Text(
              ...

Finally, combining the above code is our final Stack:

 Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.center,
      children: [
        const CircleAvatar(
          backgroundImage: AssetImage('images/head.jpg'),
          radius: 100,
        ),
        Container(
          decoration: const BoxDecoration(
            color: Colors.green,
          ),
          child: const Text(
            '编辑',
            style: TextStyle(
              fontSize: 20,
              fontWeight: FontWeight.bold,
              color: Colors.white,
            ),
          ),
        ),
      ],
    );

The interface generated by running is as follows:

Summarize

The above is the use of Stack. By stacking components, we can achieve many cool functions.

Example from this article: https://github.com/ddean2009/learn-flutter.git

For more information, please refer to http://www.flydean.com/11-flutter-ui-layout-stack/

The most popular interpretation, the most profound dry goods, the most concise tutorials, and many tricks you don't know are waiting for you to discover!

Welcome to pay attention to my official account: "Program those things", understand technology, understand you better!


flydean
890 声望433 粉丝

欢迎访问我的个人网站:www.flydean.com