Commit 882c992b authored by Adam Barth's avatar Adam Barth Committed by GitHub

Add Wrap (#9225)

The Wrap widget is a layout that places children in a run in order along its
main axis until it runs out of space. At that point, starts placing children in
a new run that is adjacent in the cross axis.

Fixes #8831
parent a559b8df
......@@ -22,13 +22,6 @@
/// initialized with those features.
library rendering;
export 'package:flutter/foundation.dart' show
VoidCallback,
ValueChanged,
ValueGetter,
ValueSetter;
export 'package:vector_math/vector_math_64.dart' show Matrix4;
export 'src/rendering/animated_size.dart';
export 'src/rendering/binding.dart';
export 'src/rendering/block.dart';
......@@ -63,3 +56,11 @@ export 'src/rendering/tweens.dart';
export 'src/rendering/view.dart';
export 'src/rendering/viewport.dart';
export 'src/rendering/viewport_offset.dart';
export 'src/rendering/wrap.dart';
export 'package:flutter/foundation.dart' show
VoidCallback,
ValueChanged,
ValueGetter,
ValueSetter;
export 'package:vector_math/vector_math_64.dart' show Matrix4;
......@@ -80,11 +80,13 @@ enum MainAxisAlignment {
/// Place the free space evenly between the children.
spaceBetween,
/// Place the free space evenly between the children as well as half of that space before and after the first and last child.
/// Place the free space evenly between the children as well as half of that
/// space before and after the first and last child.
spaceAround,
/// Place the free space evenly between the children as well as before and after the first and last child.
spaceEvenly
/// Place the free space evenly between the children as well as before and
/// after the first and last child.
spaceEvenly,
}
/// How the children should be placed along the cross axis in a flex layout.
......
......@@ -444,6 +444,13 @@ class RenderStack extends RenderBox
@override
Rect describeApproximatePaintClip(RenderObject child) => _hasVisualOverflow ? Point.origin & size : null;
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('overflow: $overflow');
description.add('alignment: $alignment');
}
}
/// Implements the same layout algorithm as RenderStack but only paints the child
......@@ -460,8 +467,8 @@ class RenderIndexedStack extends RenderStack {
FractionalOffset alignment: FractionalOffset.topLeft,
int index: 0
}) : _index = index, super(
children: children,
alignment: alignment
children: children,
alignment: alignment
);
/// The index of the child to show, null if nothing is to be displayed.
......@@ -508,4 +515,10 @@ class RenderIndexedStack extends RenderStack {
final StackParentData childParentData = child.parentData;
context.paintChild(child, childParentData.offset + offset);
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('index: $index');
}
}
This diff is collapsed.
......@@ -45,7 +45,9 @@ export 'package:flutter/rendering.dart' show
SingleChildLayoutDelegate,
TextOverflow,
ValueChanged,
ValueGetter;
ValueGetter,
WrapAlignment,
WrapCrossAlignment;
// PAINTING NODES
......@@ -2262,6 +2264,122 @@ class Expanded extends Flexible {
}) : super(key: key, flex: flex, fit: FlexFit.tight, child: child);
}
class Wrap extends MultiChildRenderObjectWidget {
Wrap({
Key key,
this.direction: Axis.horizontal,
this.alignment: WrapAlignment.start,
this.spacing: 0.0,
this.runAlignment: WrapAlignment.start,
this.runSpacing: 0.0,
this.crossAxisAlignment: WrapCrossAlignment.start,
List<Widget> children: const <Widget>[],
}) : super(key: key, children: children);
/// The direction to use as the main axis.
///
/// For example, if [direction] is [Axis.horizontal], the default, the
/// children are placed adjacent to one another in a horizontal run until the
/// available horizontal space is consumed, at which point a subsequent
/// children are placed in a new run vertically adjacent to the previous run.
final Axis direction;
/// How the children within a run should be places in the main axis.
///
/// For example, if [alignment] is [WrapAlignment.center], the children in
/// each run are grouped togeter in the center of their run in the main axis.
///
/// Defaults to [WrapAlignment.start].
///
/// See also:
///
/// * [runAlignment], which controls how the runs are placed relative to each
/// other in the cross axis.
/// * [crossAxisAlignment], which controls how the children within each run
/// are placed relative to each other in the cross axis.
final WrapAlignment alignment;
/// How much space to place between children in a run in the main axis.
///
/// For example, if [spacing] is 10.0, the children will be spaced at least
/// 10.0 logical pixels apart in the main axis.
///
/// If there is additional free space in a run (e.g., because the wrap has a
/// minimum size that is not filled or because some runs are longer than
/// others), the additional free space will be allocated according to the
/// [alignment].
///
/// Defaults to 0.0.
final double spacing;
/// How the runs themselves should be placed in the cross axis.
///
/// For example, if [runAlignment] is [WrapAlignment.center], the runs are
/// grouped togeter in the center of the overall [Wrap] in the cross axis.
///
/// Defaults to [WrapAlignment.start].
///
/// See also:
///
/// * [alignment], which controls how the children within each run are placed
/// relative to each other in the main axis.
/// * [crossAxisAlignment], which controls how the children within each run
/// are placed relative to each other in the cross axis.
final WrapAlignment runAlignment;
/// How much space to place between the runs themselves in the cross axis.
///
/// For example, if [runSpacing] is 10.0, the runs will be spaced at least
/// 10.0 logical pixels apart in the cross axis.
///
/// If there is additional free space in the overall [Wrap] (e.g., because
/// the wrap has a minimum size that is not filled), the additional free space
/// will be allocated according to the [runAlignment].
///
/// Defaults to 0.0.
final double runSpacing;
/// How the children within a run should be aligned relative to each other in
/// the cross axis.
///
/// For example, if this is set to [WrapCrossAlignment.end], and the
/// [direction] is [WrapDirection.horizontal], then the children within each
/// run will have their bottom edges aligned to the bottom edge of the run.
///
/// Defaults to [WrapCrossAlignment.start].
///
/// See also:
///
/// * [alignment], which controls how the children within each run are placed
/// relative to each other in the main axis.
/// * [runAlignment], which controls how the runs are placed relative to each
/// other in the cross axis.
final WrapCrossAlignment crossAxisAlignment;
@override
RenderWrap createRenderObject(BuildContext context) {
return new RenderWrap(
direction: direction,
alignment: alignment,
spacing: spacing,
runAlignment: runAlignment,
runSpacing: runSpacing,
crossAxisAlignment: crossAxisAlignment,
);
}
@override
void updateRenderObject(BuildContext context, RenderWrap renderObject) {
renderObject
..direction = direction
..alignment = alignment
..spacing = spacing
..runAlignment = runAlignment
..runSpacing = runSpacing
..crossAxisAlignment = crossAxisAlignment;
}
}
/// A widget that implements the flow layout algorithm.
///
/// Flow layouts are optimized for repositioning children using transformation
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment