Flutter layout (eight)-Stack, Indexedstack, GridView detailed

Source: Internet
Author: User
Tags passthrough


This paper mainly introduces stack, Indexedstack, GridView control in Flutter layout, introduces its layout behavior and usage scene in detail, atrial flutter and analyzes the source code.

1. Stack

A widgets that positions their children relative to the edges of their box.

1.1 Introduction, flutter k icks


Stacks can be analogous to absolute in the Web, heart flutter with absolute layout. Absolute layout is generally used in mobile development less, but in some scenarios, it still has its role. Of course, it can be done with stack's absolute layout, and it can be implemented with other combinations of controls.


1.2 Layout behavior


Stack layout behavior, according to whether the child is positioned or non-positioned to distinguish.


    • For positioned child nodes, their positions are determined based on the top, bottom, right, and left properties that are set, and these values are relative to the upper-top corner of the stack;
    • For non-positioned child nodes, they set the position according to the aligment of the stack.


For the order in which the child is drawn, the first child is drawn at the bottom,a flutter  followed by the previous child, similar to the Z-index in the Web. If you want to adjust the order of the display, you can do so by placing the child in the order.


1.3 Inheritance Relations

Object > Diagnosticable > DiagnosticableTree > Widget > RenderObjectWidget > MultiChildRenderObjectWidget > Stack
1.4 Sample Code


Stack(
  alignment: const Alignment(0.6, 0.6),
  children: [
    CircleAvatar(
      backgroundImage: AssetImage(‘images/pic.jpg‘),
      radius: 100.0,
    ),
    Container(
      decoration: BoxDecoration(
        color: Colors.black45,
      ),
      child: Text(
        ‘Mia B‘,
        style: TextStyle(
          fontSize: 20.0,
          fontWeight: FontWeight.bold,
          color: Colors.white,
        ),
      ),
    ),
  ],
);


Example code I used directly in the building Layouts in flutter example, the effect is as follows





1.5 Source Code parsing


The constructor functions are as follows:




Stack({
  Key key,
  this.alignment = AlignmentDirectional.topStart,
  this.textDirection,
  this.fit = StackFit.loose,
  this.overflow = Overflow.clip,
  List<Widget> children = const <Widget>[],
})
1.5.1 Attribute parsing


Alignment: Alignment, default is the upper-left corner (Topstart).



textdirection: The direction of the text, most do not need to deal with.



Fit: Defines how to set the non-positioned node size, which defaults to loose.



There are several stackfit:


    • Loose: The child node loose value, can be from min to max size;
    • Expand: The child nodes occupy as much space as possible, taking max size;
    • Passthrough: Does not change the constraints of the child nodes.


overflow: Whether the excess part is clipped (clipped).


1.5.2 Source


The stack layout code is a bit long and is explained in this segment.


      1. If the child nodes are not included, the dimensions are as large as possible.


if (childCount == 0) {
  size = constraints.biggest;
  return;
}
    • 2. According to the Fit property, set the non-positioned child node constraint condition.


switch (fit) {
  case StackFit.loose:
    nonPositionedConstraints = constraints.loosen();
    break;
  case StackFit.expand:
    nonPositionedConstraints = new BoxConstraints.tight(constraints.biggest);
    break;
  case StackFit.passthrough:
    nonPositionedConstraints = constraints;
    break;
}
    • 3. Lay out the non-positioned child nodes.


RenderBox child = firstChild;
while (child != null) {
  final StackParentData childParentData = child.parentData;
  if (!childParentData.isPositioned) {
    hasNonPositionedChildren = true;
    child.layout(nonPositionedConstraints, parentUsesSize: true);
    final Size childSize = child.size;
    width = math.max(width, childSize.width);
    height = math.max(height, childSize.height);
  }
  child = childParentData.nextSibling;
}
    • 4. Resize the stack based on whether the positioned child node is included.


if (hasNonPositionedChildren) {
  size = new Size(width, height);
} else {
  size = constraints.biggest;
}
    • 5. Finally the sub-node position adjustment, this adjustment process, according to alignment, positioned node's absolute position and so on information, the child node layout.


The first step is to lay out the constraint conditions based on the absolute position of the positioned.




if (childParentData.left != null && childParentData.right != null)
  childConstraints = childConstraints.tighten(width: size.width - childParentData.right - childParentData.left);
else if (childParentData.width != null)
  childConstraints = childConstraints.tighten(width: childParentData.width);

if (childParentData.top != null && childParentData.bottom != null)
  childConstraints = childConstraints.tighten(height: size.height - childParentData.bottom - childParentData.top);
else if (childParentData.height != null)
  childConstraints = childConstraints.tighten(height: childParentData.height);

child.layout(childConstraints, parentUsesSize: true);


The second step is the position adjustment, where the coordinates are calculated as follows:




double x;
if (childParentData.left != null) {
  x = childParentData.left;
} else if (childParentData.right != null) {
  x = size.width - childParentData.right - child.size.width;
} else {
  x = _resolvedAlignment.alongOffset(size - child.size).dx;
}

if (x < 0.0 || x + child.size.width > size.width)
  _hasVisualOverflow = true;

double y;
if (childParentData.top != null) {
  y = childParentData.top;
} else if (childParentData.bottom != null) {
  y = size.height - childParentData.bottom - child.size.height;
} else {
  y = _resolvedAlignment.alongOffset(size - child.size).dy;
}

if (y < 0.0 || y + child.size.height > size.height)
  _hasVisualOverflow = true;

childParentData.offset = new Offset(x, y);
1.6 Usage Scenarios


The stack scene is still more, and you can generally use a stack for layouts that require overlay display. Some scenarios can also be replaced by other controls, we should choose the less expensive controls to implement.


2. Indexedstack

A Stack, that shows a, and from a list of children.

2.1 Introduction


Indexedstack inherits from the stack, its role is to display the index child, other child is not visible. So the size of the indexedstack is always the same size as the largest child node.


2.2 Examples


In this case, the example of the stack is modified slightly, and the index is set to 1, which is the node that displays the container with text.




Container(
  color: Colors.yellow,
  child: IndexedStack(
    index: 1,
    alignment: const Alignment(0.6, 0.6),
    children: [
      CircleAvatar(
        backgroundImage: AssetImage(‘images/pic.jpg‘),
        radius: 100.0,
      ),
      Container(
        decoration: BoxDecoration(
          color: Colors.black45,
        ),
        child: Text(
          ‘Mia B‘,
          style: TextStyle(
            fontSize: 20.0,
            fontWeight: FontWeight.bold,
            color: Colors.white,
          ),
        ),
      ),
    ],
  ),
)




2.3 Source Code parsing


Its drawing code is very simple, because it inherits from the stack, the layout performance is basically consistent, the difference is that when it is drawn, only the first child is drawn.




@override
void paintStack(PaintingContext context, Offset offset) {
if (firstChild == null || index == null)
  return;
final RenderBox child = _childAtIndex();
final StackParentData childParentData = child.parentData;
context.paintChild(child, childParentData.offset + offset);
}
2.4 Usage Scenarios


If you need to show one of a bunch of controls, you can use Indexedstack. There are certain usage scenarios, but there are controls that can implement their functions, but they may be more complex to manipulate.


3. GridView

A scrollable, 2D array of widgets.

3.1 Introduction


The GridView is very common on the mobile side, is a scrolling multi-column list, the actual use of the scene is also very much.


3.2 Layout behavior


The layout behavior of the GridView is not complex, itself is to occupy the space area as far as possible, the layout behavior completely inherits from ScrollView.


3.3 Inheritance Relations

Object > Diagnosticable > DiagnosticableTree > Widget > StatelessWidget > ScrollView > BoxScrollView > GridView


From the perspective of inheritance, the GridView is encapsulated on a scrollview basis, similar to the mobile side.


3.4 Sample Code


GridView.count(
  crossAxisCount: 2,
  children: List.generate(
    100,
    (index) {
      return Center(
        child: Text(
          ‘Item $index‘,
          style: Theme.of(context).textTheme.headline,
        ),
      );
    },
  ),
);


The example code directly uses the example in the creating a Grid list to create a list of a total of 100 child nodes in a 2 column.


3.5 Source Code parsing


The default constructor is as follows:




GridView({
  Key key,
  Axis scrollDirection = Axis.vertical,
  bool reverse = false,
  ScrollController controller,
  bool primary,
  ScrollPhysics physics,
  bool shrinkWrap = false,
  EdgeInsetsGeometry padding,
  @required this.gridDelegate,
  bool addAutomaticKeepAlives = true,
  bool addRepaintBoundaries = true,
  double cacheExtent,
  List<Widget> children = const <Widget>[],
})


It also provides the following additional four construction methods, which are easy for developers to use.




GridView.builder
GridView.custom
GridView.count
GridView.extent
3.5.1 Attribute parsing


scrolldirection: The direction of scrolling, vertical and horizontal, the default is the vertical direction (axis.vertical).



Reverse: The default is to scroll from top or left down or right, this property controls whether it is reversed, the default value is False, and does not scroll backwards.



controller: Controls the position of the child when scrolling.



Primary: is the main scrolling view associated with the Primaryscrollcontroller of the parent node.



Physics: How the scrolling view responds to the user's input.



shrinkwrap: Whether scrolling view content in scrolling direction should be determined by what is being viewed.



padding: A blank area around it.



griddelegate: Controls the delegate of the GridView sub-node layout.



cacheextent: Cache area.


3.5.2 Source


@override
Widget build(BuildContext context) {
  final List<Widget> slivers = buildSlivers(context);
  final AxisDirection axisDirection = getDirection(context);

  final ScrollController scrollController = primary
    ? PrimaryScrollController.of(context)
    : controller;
  final Scrollable scrollable = new Scrollable(
    axisDirection: axisDirection,
    controller: scrollController,
    physics: physics,
    viewportBuilder: (BuildContext context, ViewportOffset offset) {
      return buildViewport(context, offset, axisDirection, slivers);
    },
  );
  return primary && scrollController != null
    ? new PrimaryScrollController.none(child: scrollable)
    : scrollable;
}


The above code is the ScrollView build method, and the GridView is a special scrollview. GridView itself code is nothing, basically is scrollview on the things, mainly involves scrollable, sliver, viewport and other content, these content is more, so the source code is first slightly, A separate article in the back to analyze the ScrollView.


3.6 Usage Scenarios


Use a lot of scenes, very common controls. There are also controls that can implement their functions, such as the official said, the GridView is actually a silvers that contains only one Silvergrid Customscrollview.


4. Something


The author has built a flutter study related projects, GitHub address, which contains the author of the Flutter study related to some of the articles, will be updated regularly, will also upload some learning demo, welcome attention.


5. Reference
    1. Stack class
    2. Indexedstack class
    3. GridView class
    4. ScrollView class


Flutter layout (eight)-Stack, Indexedstack, GridView detailed


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.