This article mainly introduces Container, which is very common in Flutter, and gives some practical examples on how to use it.

1. Introduction

A convenience widget that combines common painting, positioning, and sizing widgets.

Containers are all too common in Flutter. The official description is a widget that combines painting, positioning, and sizing widgets.

It is a composite widget with drawing widgets, positioning widgets, and sizing widgets inside. Many of the widgets you’ll see later are made up of more basic widgets.

Composition of 1.1

The components of a Container are as follows:

  • The innermost layer is the child element;
  • The child element is first wrapped in the padding;
  • Then add additional constraints to the constraints;
  • Finally add margin.

The process for drawing containers is as follows:

  • The transform effect is drawn first;
  • Next, draw decoration;
  • Then draw child;
  • Finally, draw the ground decoration.

The Container can be adjusted in two ways:

  • The Container tries to be large enough when it has no children. Unless constraints are unbounded, in which case the Container will try to be small enough.
  • The Container of the string node resizesaccording to the size of its children, but the Container constructor resizesaccording to the parameters in the constructor if the Container constructor contains width, height, and constraints.

1.2 Layout Behavior

The layout behavior of a Container can be complex because it combines a series of widgets that have their own layout behavior.

Typically, Containers try the layout in the following order:

  • Alignment C.
  • Adjust its size to fit the child node;
  • Uses width, height, and constraints layouts;
  • Extend itself to fit the parent node;
  • Adjust yourself to be small enough.

Further:

  • If there are no children, width, height, and constraints are not set, and the parent has no unbounded limits, the Container will adjust itself to be small enough.
  • If the Container does not have child nodes or an alignment, but provides width, height, or constraints, then the Container adjusts itself to be small enough based on its limitations and those of the parent node.
  • If there are no children, width, height, constraints, and alignment, but the parent provides a bounded limit, then the Container will adjust itself to the parent’s limit to be large enough.
  • If the parent provides unbounded limits in alignment, the Container will adjust its size to enclose the child.
  • If alignment is available and the parent node provides a bounded limit, the Container will adjust itself sufficiently (within the parent node’s scope), and then adjust the position of the child according to alignment.
  • Contains child, but does not have width, height, constraints, or alignment. The Container passes the parent’s constraints to the child and adjusts itself to the child.

Margin and padding attributes also affect the layout.

1.3 Inheritance Relationship

Object > Diagnosticable > DiagnosticableTree > Widget > StatelessWidget > Container
Copy the code

As you can see from the inheritance relationship, the Container is a StatelessWidget. A Container is not a basic widget; it is made up of a series of basic widgets.

2. Source code analysis

Constructors are as follows:

Container({
    Key key,
    this.alignment,
    this.padding,
    Color color,
    Decoration decoration,
    this.foregroundDecoration,
    double width,
    double height,
    BoxConstraints constraints,
    this.margin,
    this.transform,
    this.child,
  })
Copy the code

The most commonly used attributes are the padding, color, width, height and margin attributes.

2.1 Attribute Resolution

Key: Unique identifier of Container, used to search for updates.

Alignment: Controls the alignment of the child. This attribute takes effect if the Container or its parent is larger than the child size. There are many alignment options.

Padding: The empty area inside the decoration. If there is a child, the child is inside the padding. The difference between padding and margin is that padding is contained within the content, while margin is the outer boundary. If you set the click event, the padding area will respond, but the margin area will not.

Color: Used to set the background color of the container. If the foregroundDecoration is set, the color effect may be obscured.

“Decoration” : the decoration behind the child. If “decoration” is set, the color attribute cannot be set. Otherwise, an error will be reported, and the color should be set in “decoration”.

ForegroundDecoration: Decoration painted in front of child.

Width: the width of the container, set to double. Infinity can be used to force the container to be full in width.

Height: The height of the container, set to double. Infinity forces the container to be full at the height.

Constraints: Additional constraints added to the child.

Margin: The blank area surrounding decoration and child, not part of the content area.

Transform: Sets the transformation matrix of container. The type is Matrix4.

Child: Content widget in container.

2.2 An example

new Container( constraints: New BoxConstraints. Expand (height: the Theme of (context). TextTheme. Display1. FontSize * 1.1 + 200.0,), decoration: New BoxDecoration(border: new border. All (width: 2.0, color: color.red), color: color.grey, borderRadius: New Borderradius.all (new radius.circular (20.0)), image: new DecorationImage(image: new NetworkImage('http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c0 86e06f06c.jpg'), centerSlice: new rect.fromltrb (270.0, 180.0, 1360.0, 730.0),), padding: const EdgeInsets. All (8.0), alignment: Alignment.center, child: new Text('Hello World', style: the Theme of (context). TextTheme. Display1. CopyWith (color: Colors. Black)), the transform: new Matrix4. RotationZ (0.3),)Copy the code

This is a variation of the example given in the official documentation, including more complete attributes, you can see its usage. The actual running effect is as follows:

You can set the border, background color, background picture, rounded corner and other properties, decoration is very practical. For the transform property, those who have experience in the development of other platforms generally understand that the transform is not the actual position of the transform, but the drawing effect of the transform. That is to say, its click, size, spacing, etc., are all in accordance with before the transform.

2.3 the source code

decoration = decoration ?? (color ! = null ? new BoxDecoration(color: color) : null),Copy the code

It can be seen that the setting of color is changed to decoration for drawing. If both decoration and color are included, an error will be reported.

@override
  Widget build(BuildContext context) {
    Widget current = child;

    if(child == null && (constraints == null || ! IsTight) {current = new LimitedBox(maxWidth: 0.0, maxHeight: 0.0, child: new ConstrainedBox(constraints: const BoxConstraints.expand()) ); }if(alignment ! = null) current = new Align(alignment: alignment, child: current); final EdgeInsetsGeometry effectivePadding = _paddingIncludingDecoration;if(effectivePadding ! = null) current = new Padding(padding: effectivePadding, child: current);if(decoration ! = null) current = new DecoratedBox(decoration: decoration, child: current);if(foregroundDecoration ! = null) { current = new DecoratedBox( decoration: foregroundDecoration, position: DecorationPosition.foreground, child: current ); }if(constraints ! = null) current = new ConstrainedBox(constraints: constraints, child: current);if(margin ! = null) current = new Padding(padding: margin, child: current);if(transform ! = null) current = new Transform(transform: transform, child: current);return current;
  }
Copy the code

The build function of a Container is not long, and drawing is a linear judgment process, covering widgets layer by layer to implement different styles.

The innermost layer is child, and if empty or other constraints, the innermost layer contains a LimitedBox, Then Align, Padding, DecoratedBox, foreground DecoratedBox, ConstrainedBox, Padding, Transform.

The source code for Container itself is not complicated, but rather its various layout representations. Keep in mind that if there are no internal constraints, then as large as the parent node can be, if there are internal constraints, then as large as the parent node can be.

2.4 Application Scenarios

Container is one of the most frequently used widgets in the current project. In practice, I use Containers in the following situations, but not always, but also through other widgets.

  • You need to set the interval (in this case, if it’s just a pure interval, you can also use Padding);
  • Need to set the background color;
  • When you need to set rounded corners or borders (ClipRRect can also be rounded);
  • Need to Align (Align also works);
  • When the background image needs to be set (Stack can also be used).

Example 3.

Let’s try to make a rounded button that contains the following features:

  • Support to set the three states of the button (normal, click, disable) color value;
  • Support setting button title;
  • Support setting width and height;
  • Support for clickback;

According to the above introduction, the effect can be basically completed by using the property decoration. As for the click effect and click callback, a GestureDetector can be completed. The actual example is very simple, so I won’t post the code here. The actual running effect is as follows:

3.1 Precautions

This small control is easy to write and does not have any difficulty in writing. It simply introduces how to use Containers, but there is one important point to note. In the control’s deactivate state, we need to initialize the control’s properties to their original state. For example, in this case, we have the following code:

  @override
  void deactivate() {
    super.deactivate();
    currentColor = widget.backgroundColor;
  }
Copy the code

Why did you do that? When you click the button to jump to the page, the button is still in the clicked state. When you return to the page, the page is still in the clicked state. Therefore, you need to manually restore the control to its initial state in the deactivate state. However, this color setting does not mean that the control will be refreshed immediately at the deactivate stage. Instead, the next time you go to the page and run the build again, the control will be drawn to the original state.

3.2 code

Github address. This is a series of projects that will introduce, if nothing else, more than 20 layout widgets common to Flutter.

4. The latter

The author has set up a project about flutter learning. The github address contains some articles about flutter learning written by the author. They will be updated regularly and some learning demos will also be uploaded.

Reference 5.

  1. Container class