In the previous article, we said:

Linear layout –Flutter layout controls –>Row, Column

Flexible layout –Flutter layout control text –>Flex, Expanded

Let’s talk about streaming layout

In a linear layout Row, an overflow error is reported if the child widget is outside the screen, such as:

Row(
  children: <Widget>[
    Text("xxx"*100)
  ],
);
Copy the code

Operation effect:

So one might say, why not use maxLines and Overflow in the Text component?

Obviously, the main axis of the Row component is horizontal, so that its content is arranged horizontally. By default, a Row has only one line and does not fold if it goes beyond the screen. These two properties, when added together, have no effect

However, if you replace Row with Column, these two attributes will come into play

But if we use the two properties above, that’s not good either, because you’re not sure how much content there is, so we want it to fold automatically if it goes beyond the screen, and this layout is called streaming layout.

Flutter supports streaming layout through Wrap and Flow

Wrap

A streaming layout component that automatically folds if the content width exceeds the screen width

The source code example

The Wrap constructor:

Wrap({ ... Horizontal = Axis. Horizontal, this.alignment = WrapAlignment. Start, this.spacing = 0.0, This. RunAlignment = WrapAlignment. Start, enclosing runSpacing = 0.0, enclosing crossAxisAlignment = WrapCrossAlignment. Start, this.textDirection, this.verticalDirection = VerticalDirection.down, List<Widget> children = const <Widget>[], })Copy the code

Attribute interpretation

We can see that many of the Wrap properties are also present in Row, Column, and Flex,

If you don’t know the properties of the Flutter layout controls, go to the following steps: Flutter layout controls –>Row, Column

There are several properties that are unique to Wrap

spacing

The spacing of subcomponents in the main axis should be familiar if you have learned HTML and CSS

In this case, there are gaps between components

Such as:

Wrap(
  spacing: 20,
  children: <Widget>[
	Text("xxx"),
	Text('yyy')
  ],
)
Copy the code

Spacing: 20 indicates the distance between XXX and YYy

runSpacing

Spacing of components along the vertical axis, without too much explanation

alignment

The alignment of the vertical axis

Such as:

Wrap (spacing: 20, / / spindle direction (horizontal) spacing runSpacing: 50, / / spacing of the vertical axis direction alignment: WrapAlignment. Center, / / along the major axis center children: <Widget>[ Text("xxx"*20), Text('yyy') ], )Copy the code

Operation effect:

Flow

Flow is rarely used because it is too complex. Flow is mainly used in scenarios where a custom layout strategy is required or where performance is required (such as in animation).

Advantages:

  • Performance is good; Flow is a very efficient control for adjusting the size and position of subcomponents. Flow is optimized when adjusting the position of subcomponents with the transformation matrix: After Flow positioning, if the size or position of the child component changes, the paintChild method in FlowDelegate is called context.paintChild for redrawing, and context.PaintChild uses the transition matrix for redrawing. There is no actual adjustment of the component position.

  • Flexible; Since we need to implement the FlowDelegate’s paintChildren() method ourselves, we need to calculate the position of each component ourselves, so we can customize the layout strategy.

Disadvantages:

  • Complex to use.

  • You cannot customize the child component size and must return a fixed size either by specifying the parent container size or by implementing TestFlowDelegate’s getSize.

Example:

Custom streaming layout for six color blocks:

Flow(delegate: TestFlowDelegate(margin: edgeinset.all (10.0)), children: <Widget>[new Container(width: Color: color.red,), new Container(width: 80.0, height:80.0, color: color.red,) Color.green,), new Container(width: 80.0, height:80.0, color: color.blue,), new Container(width: 80.0, height:80.0, color: color.blue,), new Container(width: Color: color.yellow,), new Container(width: 80.0, height:80.0, color: color.yellow,) Colors. Brown,), new Container(width: 80.0, height:80.0, color: color.purple,),],)Copy the code

Implement TestFlowDelegate:

class TestFlowDelegate extends FlowDelegate { EdgeInsets margin = EdgeInsets.zero; TestFlowDelegate({this.margin}); @override void paintChildren(FlowPaintingContext context) { var x = margin.left; var y = margin.top; // Calculate the position of each widget for (int I = 0; i < context.childCount; i++) { var w = context.getChildSize(i).width + x + margin.right; If < context. The size. The width (w) {context. PaintChild (I, transform: new Matrix4 translationValues (x, y, 0.0)); x = w + margin.left; } else { x = margin.left; y += context.getChildSize(i).height + margin.top + margin.bottom; / / draw the child widgets (optimization) context. PaintChild (I, transform: new Matrix4 translationValues (x, y, 0.0)); x += context.getChildSize(i).width + margin.left + margin.right; }}} @override getSize(BoxConstraints constraints){return Size(double. Infinity,200.0); } @override bool shouldRepaint(FlowDelegate oldDelegate) { return oldDelegate ! = this; }}Copy the code

Operation effect:

As you can see, our main task is to implement paintChildren, whose main task is to determine the location of each child widget. Since Flow is not adaptive to the size of the child widgets, we specify the size of the Flow by returning a fixed size on getSize.

portal

Flutter layout controls –>Align, Center

21. Stack, tourists

Flutter layout controls –>Flex, Expanded

Flutter layout controls –>Row, Column


V_V