This is the 12th day of my participation in Gwen Challenge

preface

We are going to talk about Stack layout. We can call it Stack layout, also called hierarchical layout, mainly to display the overlapping layout of the plane, which can be more flexible control of the location of sub-items.

Simple to use

So let’s add three different sizes here, and see how they stack up.

Stack(
  children: [
    getItem(3, width: 120, height: 120, color: Colors.purple),
    getItem(2, width: 80, height: 80, color: Colors.blue),
    getItem(1),,)Copy the code

getItem

Except for index, all parameters are selected


/// Get the subproject (using the selection parameter)
Widget getItem(int index,
               {double? width = 60.double? height = 60, Color color = Colors.orange}) {
  return Container(
    // Set width and height to 60
    width: width,
    height: height,
    // Set the background color
    color: color,
    // Set the gap
    margin: EdgeInsets.all(2),
    // Center the subitem
    alignment: Alignment.center,
    // Set the child
    child: Text('$index')); }Copy the code

See the effect

Alignment (alignment)

If you look at the source code as you can see the default value of this parameter is AlignmentDirectional topStart, but here we can still use our familiar Alignment. The topLeft to parameter Settings, is this why? Take a look at the AlignmentDirectional source code, which we looked at in the previous section

Stack(
  // Center and align
  alignment: Alignment.topLeft,
  children: [
    getItem(3, width: 120, height: 120, color: Colors.purple),
    getItem(2, width: 80, height: 80, color: Colors.blue),
    getItem(1),,)Copy the code

Alignment and AlignmentDirectional source

// Alignment
class Alignment extends AlignmentGeometry {
  /// Creates an alignment.
  ///
  /// The [x] and [y] arguments must not be null.
  const Alignment(this.x, this.y)
    : assert(x ! =null),
      assert(y ! =null);
  static const Alignment topLeft = Alignment(1.0.1.0);
  static const Alignment center = Alignment(0.0.0.0); . }// AlignmentDirectional
class AlignmentDirectional extends AlignmentGeometry {
  const AlignmentDirectional(this.start, this.y)
    : assert(start ! =null),
      assert(y ! =null);
  static const AlignmentDirectional topStart = AlignmentDirectional(1.0.1.0);
  // Consider using Alignment. Center instead
  static const AlignmentDirectional center = AlignmentDirectional(0.0.0.0); . }Copy the code

We have posted the core source code above, it can be seen that they both inherit AlignmentGeometry, and then the implementation is similar, and the comments in the source code also recommend us to use Alignment instead

Various alignment effects

Here we use Alignment

Alignment.topLeft Alignment.topCenter Alignment.topRight
Alignment.centerLeft Alignment.center Alignment.centerRight
Alignment.bottomLeft Alignment.bottomCenter Alignment.bottomRight

Learn some skills

When we enter parameters such as **Alignment. BottomRight **, which is too cumbersome to input all at once, we can enter part of the prefix + the first letter of the constant, as follows

  • Alignment.bottomRight => alibr

  • Alignment.center => alic

Read my article and you will find that there are not only source code analysis, structure combing and various practical skills, remember to pay attention to me oh

Fit (filling method)

To demonstrate the effect, let’s add a background BgContainer (the generic component of the previous chapter wrapper)

BgContainer(
  child: Stack(
    / / in the middle
    alignment: Alignment.center,
    // Set the default value loose
    fit: StackFit.loose,
    children: [
      getItem(3, width: 120, height: 120, color: Colors.purple),
      getItem(2, width: 80, height: 80, color: Colors.blue),
      getItem(1)],),)Copy the code

Stackfit.loose (loose) – Default

Here we use DevTools for the effectWidget InspectorTo debug the layout and maybe talk about Flutter DevTools usage techniques later (no promises here, but may come back)



As you can see from the figure above, the size of the Stack depends on the largest of the subitems (i.ePurple 120Width and height subterm)

It’s time to expand.



This doesn’t seem to be quite as expected. Shouldn’t it be possible to expand the Stack to maximum?

Currently our subitems are unpositioned, so all subclass constraints are extended to match the maximum value of the Stack

Add the position

So let’s change it a little bit and see what it looks like. Let’s look at the code

BgContainer(
  child: Stack(
    alignment: Alignment.center,
    fit: StackFit.expand,
    children: [
      getItem(3, width: 120, height: 120, color: Colors.purple),
      getItem(2, width: 80, height: 80, color: Colors.blue),
      // This adds positioning
      Positioned(
        // 10 to the left
        left: 10.// 10 from the top
        top: 10,
        child: getItem(1(), (], (), (Copy the code



Now that I see the effect,1 yellowThe subitem follows its own constraints because it adds the location, and the others2, 3,And because no location is addedStackThe same size, the constraint is passed.

Here we temporarily do not talk about the use of positioning, the next part of our system chat

StackFit. Passthrough

So let’s see what happens



This seems to be the samelooseWhat difference does it make? We can take a look at the source code and change it to the sample code below

BgContainer(
  // Add a horizontal layout
  child: Row(
    children: [
      // Add the expansion component, which can be seen in the column
      Expanded(
        child: Stack(
          alignment: Alignment.center,
          // Set the filling method to passthrough
          fit: StackFit.passthrough,
          children: [
            getItem(3, width: 120, height: 120, color: Colors.purple),
            getItem(2, width: 80, height: 80, color: Colors.blue),
            Positioned(
              left: 10,
              top: 10,
              child: getItem(1() [() [() [() [() [()Copy the code



Here we see the vsexpandIt’s a little bit different, but here we’re just expanding the width, and the height is still the height of the subterm. Because hereStackThe width constraint is the expanded screen width, which is passed directly to the child component without adding positioning, so see2, 3,The subcomponents then change, and1The size of the child component has not changed.

What happens if it is loose?

Alignment and subitem constraints continue for non-positioned components

A small summary

clipBehavior

Because this article is based on Flutter 2.2.1, overflow has been deprecated. Many clipping behaviors will be changed to clipBehavior in future. This is a parameter we discussed earlier in The Clipping article “The Use of various clipping widgets in Flutter”

How do we expect to crop the render when we set the size of the child to be larger than the Stack layout? Clipping or display, anti-aliasing or no aliasing?

BgContainer(
  child: Stack(
    alignment: Alignment.center,
    fit: StackFit.passthrough,
    // Set clipping behavior to hardEdge by default
    clipBehavior: Clip.hardEdge,
    children: [
      getItem(3, width: 120, height: 120, color: Colors.purple),
      getItem(2, width: 80, height: 80, color: Colors.blue),
      // Set this to position the upper left corner -20
      Positioned(
        left: - 20,
        top: - 20,
        child: getItem(1(), (], (), (Copy the code

See the effect

Clip.none (not clipping) Clip.hardEdge AntiAlias, antiAliasWithSaveLayer

It is generally set by default and not clipping. For others, you can refer back to the clipping chapter for the differences.

So that wraps up the Stack core, and in the next video we combine the positioning component “jam, Align”, so keep your eyes on my column

Source warehouse

Based on the latest version of Flutter 🔥

  • Flutter Widgets warehouse

Refer to the link

  • Stack (Flutter Widget of the Week)
  • Flutter-Stack

Pay attention to column

  • This article has been included in the column at 👇 below, you can follow it directly
  • Read more | The series continues to be updated

👏 welcome to like ➕ collect ➕ pay attention, please feel free to comment on 👇 if you have any questions, I will reply as soon as possible