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