[Reland] Introduce double Flex.spacing parameter for Row/Column spacing (#152890)

Relands https://github.com/flutter/flutter/pull/152472 (Fixed error causing message test, maybe by https://github.com/flutter/flutter/pull/152501)

---

fixes [add spacing parameter to Column and Row](https://github.com/flutter/flutter/issues/55378)

### `Column.spacing` Code sample

<details>
<summary>expand to view the code sample</summary> 

```dart
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.black,
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: DecoratedBox(
              decoration: BoxDecoration(
                  border: Border.all(
                color: Colors.amber,
              )),
              child: const Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  Column(
                    spacing: 40.0,
                    // ignore: avoid_redundant_argument_values
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.topCenter,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.bottomCenter,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Column(
                    spacing: 40.0,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.topCenter,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.bottomCenter,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Column(
                    spacing: 40.0,
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.topCenter,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.bottomCenter,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Column(
                    spacing: 40.0,
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.topCenter,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.bottomCenter,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Column(
                    spacing: 40.0,
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.topCenter,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.bottomCenter,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Column(
                    spacing: 40.0,
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.topCenter,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.bottomCenter,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}
```

</details>

### Preview

<img width="1072" alt="Screenshot 2024-07-30 at 15 40 59" src="https://github.com/user-attachments/assets/14f21091-9e46-4a58-8552-1379f4ba9216">

### `Row.spacing` Code sample

<details>
<summary>expand to view the code sample</summary> 

```dart
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.black,
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: DecoratedBox(
              decoration: BoxDecoration(
                  border: Border.all(
                color: Colors.amber,
              )),
              child: const Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  Row(
                    spacing: 40.0,
                    // ignore: avoid_redundant_argument_values
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerLeft,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerRight,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Row(
                    spacing: 40.0,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerLeft,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerRight,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Row(
                    spacing: 40.0,
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerLeft,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerRight,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Row(
                    spacing: 40.0,
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerLeft,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerRight,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Row(
                    spacing: 40.0,
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerLeft,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerRight,
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Row(
                    spacing: 40.0,
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      ColoredBox(
                        color: Color(0xffff0000),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            alignment: Alignment.centerLeft,
                            child: Text(
                              'RED',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff00ff00),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Center(
                            child: Text(
                              'GREEN',
                              style: TextStyle(color: Colors.black),
                            ),
                          ),
                        ),
                      ),
                      ColoredBox(
                        color: Color(0xff0000ff),
                        child: SizedBox(
                          width: 50.0,
                          height: 75.0,
                          child: Align(
                            child: Text(
                              'BLUE',
                              style: TextStyle(color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

```

</details>

### Preview

<img width="1072" alt="Screenshot 2024-07-30 at 15 39 42" src="https://github.com/user-attachments/assets/717e9f5e-a491-4853-ba74-e72ec7493363">
This commit is contained in:
Taha Tesser 2024-08-06 02:04:50 +03:00 committed by GitHub
parent 173bf86b7b
commit 00ef750d28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 618 additions and 18 deletions

View File

@ -215,19 +215,19 @@ enum MainAxisAlignment {
/// after the first and last child.
spaceEvenly;
(double leadingSpace, double betweenSpace) _distributeSpace(double freeSpace, int itemCount, bool flipped) {
(double leadingSpace, double betweenSpace) _distributeSpace(double freeSpace, int itemCount, bool flipped, double spacing) {
assert(itemCount >= 0);
return switch (this) {
MainAxisAlignment.start => flipped ? (freeSpace, 0.0) : (0.0, 0.0),
MainAxisAlignment.start => flipped ? (freeSpace, spacing) : (0.0, spacing),
MainAxisAlignment.end => MainAxisAlignment.start._distributeSpace(freeSpace, itemCount, !flipped),
MainAxisAlignment.spaceBetween when itemCount < 2 => MainAxisAlignment.start._distributeSpace(freeSpace, itemCount, flipped),
MainAxisAlignment.spaceAround when itemCount == 0 => MainAxisAlignment.start._distributeSpace(freeSpace, itemCount, flipped),
MainAxisAlignment.end => MainAxisAlignment.start._distributeSpace(freeSpace, itemCount, !flipped, spacing),
MainAxisAlignment.spaceBetween when itemCount < 2 => MainAxisAlignment.start._distributeSpace(freeSpace, itemCount, flipped, spacing),
MainAxisAlignment.spaceAround when itemCount == 0 => MainAxisAlignment.start._distributeSpace(freeSpace, itemCount, flipped, spacing),
MainAxisAlignment.center => (freeSpace / 2.0, 0.0),
MainAxisAlignment.spaceBetween => (0.0, freeSpace / (itemCount - 1)),
MainAxisAlignment.spaceAround => (freeSpace / itemCount / 2, freeSpace / itemCount),
MainAxisAlignment.spaceEvenly => (freeSpace / (itemCount + 1), freeSpace / (itemCount + 1)),
MainAxisAlignment.center => (freeSpace / 2.0, spacing),
MainAxisAlignment.spaceBetween => (0.0, freeSpace / (itemCount - 1) + spacing),
MainAxisAlignment.spaceAround => (freeSpace / itemCount / 2, freeSpace / itemCount + spacing),
MainAxisAlignment.spaceEvenly => (freeSpace / (itemCount + 1), freeSpace / (itemCount + 1) + spacing),
};
}
}
@ -390,6 +390,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
VerticalDirection verticalDirection = VerticalDirection.down,
TextBaseline? textBaseline,
Clip clipBehavior = Clip.none,
double spacing = 0.0,
}) : _direction = direction,
_mainAxisAlignment = mainAxisAlignment,
_mainAxisSize = mainAxisSize,
@ -397,7 +398,9 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
_textDirection = textDirection,
_verticalDirection = verticalDirection,
_textBaseline = textBaseline,
_clipBehavior = clipBehavior {
_clipBehavior = clipBehavior,
_spacing = spacing,
assert(spacing >= 0.0) {
addAll(children);
}
@ -588,6 +591,69 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
}
}
/// {@template flutter.rendering.RenderFlex.spacing}
/// How much space to place between children in the main axis.
///
/// The spacing is only applied between children in the main axis.
///
/// If the [spacing] is 10.0 and the [mainAxisAlignment] is
/// [MainAxisAlignment.start], then the first child will be placed at the start
/// of the main axis, and the second child will be placed 10.0 pixels after
/// the first child in the main axis, and so on. The [spacing] is not applied
/// before the first child or after the last child.
///
/// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.end],
/// then the last child will be placed at the end of the main axis, and the
/// second-to-last child will be placed 10.0 pixels before the last child in
/// the main axis, and so on. The [spacing] is not applied before the first
/// child or after the last child.
///
/// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.center],
/// then the children will be placed in the center of the main axis with 10.0
/// pixels of space between the children. The [spacing] is not applied before the first
/// child or after the last child.
///
/// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.spaceBetween],
/// then there will be a minimum of 10.0 pixels of space between each child in the
/// main axis. If the free space is 100.0 pixels between the two children,
/// then the minimum space between the children will be 10.0 pixels and the
/// remaining 90.0 pixels will be the free space between the children. The
/// [spacing] is not applied before the first child or after the last child.
///
/// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.spaceAround],
/// then there will be a minimum of 10.0 pixels of space between each child in the
/// main axis, and the remaining free space will be placed between the children as
/// well as before the first child and after the last child. The [spacing] is
/// not applied before the first child or after the last child.
///
/// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.spaceEvenly],
/// then there will be a minimum of 10.0 pixels of space between each child in the
/// main axis, and the remaining free space will be evenly placed between the
/// children as well as before the first child and after the last child. The
/// [spacing] is not applied before the first child or after the last child.
///
/// When the [spacing] is non-zero, the layout size will be larger than
/// the sum of the children's layout sizes in the main axis.
///
/// When the total children's layout sizes and total spacing between the
/// children is greater than the maximum constraints in the main axis, then
/// the children will overflow. For example, if there are two children and the
/// maximum constraint is 100.0 pixels, the children's layout sizes are 50.0
/// pixels each, and the spacing is 10.0 pixels, then the children will
/// overflow by 10.0 pixels.
///
/// Defaults to 0.0.
/// {@endtemplate}
double get spacing => _spacing;
double _spacing;
set spacing (double value) {
if (_spacing == value) {
return;
}
_spacing = value;
markNeedsLayout();
}
@override
void setupParentData(RenderBox child) {
if (child.parentData is! FlexParentData) {
@ -597,15 +663,15 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
double _getIntrinsicSize({
required Axis sizingDirection,
required double extent, // the extent in the direction that isn't the sizing direction
required _ChildSizingFunction childSize, // a method to find the size in the sizing direction
required double extent, // The extent in the direction that isn't the sizing direction.
required _ChildSizingFunction childSize, // A method to find the size in the sizing direction.
}) {
if (_direction == sizingDirection) {
// INTRINSIC MAIN SIZE
// Intrinsic main size is the smallest size the flex container can take
// while maintaining the min/max-content contributions of its flex items.
double totalFlex = 0.0;
double inflexibleSpace = 0.0;
double inflexibleSpace = spacing * (childCount - 1);
double maxFlexFractionSoFar = 0.0;
for (RenderBox? child = firstChild; child != null; child = childAfter(child)) {
final int flex = _getFlex(child);
@ -825,7 +891,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
case Axis.vertical:
final double freeSpace = math.max(0.0, sizes.mainAxisFreeSpace);
final bool flipMainAxis = _flipMainAxis;
final (double leadingSpaceY, double spaceBetween) = mainAxisAlignment._distributeSpace(freeSpace, childCount, flipMainAxis);
final (double leadingSpaceY, double spaceBetween) = mainAxisAlignment._distributeSpace(freeSpace, childCount, flipMainAxis, spacing);
double y = flipMainAxis
? leadingSpaceY + (childCount - 1) * spaceBetween + (sizes.axisSize.mainAxisExtent - sizes.mainAxisFreeSpace)
: leadingSpaceY;
@ -978,7 +1044,8 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
int totalFlex = 0;
RenderBox? firstFlexChild;
_AscentDescent accumulatedAscentDescent = _AscentDescent.none;
_AxisSize accumulatedSize = _AxisSize.empty;
// Initially, accumulatedSize is the sum of the spaces between children in the main axis.
_AxisSize accumulatedSize = _AxisSize._(Size(spacing * (childCount - 1), 0.0));
for (RenderBox? child = firstChild; child != null; child = childAfter(child)) {
final int flex;
if (canFlex && (flex = _getFlex(child)) > 0) {
@ -1064,7 +1131,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
final double remainingSpace = math.max(0.0, sizes.mainAxisFreeSpace);
final bool flipMainAxis = _flipMainAxis;
final bool flipCrossAxis = _flipCrossAxis;
final (double leadingSpace, double betweenSpace) = mainAxisAlignment._distributeSpace(remainingSpace, childCount, flipMainAxis);
final (double leadingSpace, double betweenSpace) = mainAxisAlignment._distributeSpace(remainingSpace, childCount, flipMainAxis, spacing);
final (_NextChild nextChild, RenderBox? topLeftChild) = flipMainAxis ? (childBefore, lastChild) : (childAfter, firstChild);
final double? baselineOffset = sizes.baselineOffset;
assert(baselineOffset == null || (crossAxisAlignment == CrossAxisAlignment.baseline && direction == Axis.horizontal));
@ -1192,5 +1259,6 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
properties.add(EnumProperty<VerticalDirection>('verticalDirection', verticalDirection, defaultValue: null));
properties.add(EnumProperty<TextBaseline>('textBaseline', textBaseline, defaultValue: null));
properties.add(DoubleProperty('spacing', spacing, defaultValue: null));
}
}

View File

@ -4604,6 +4604,7 @@ class Flex extends MultiChildRenderObjectWidget {
this.verticalDirection = VerticalDirection.down,
this.textBaseline, // NO DEFAULT: we don't know what the text's baseline should be
this.clipBehavior = Clip.none,
this.spacing = 0.0,
super.children,
}) : assert(!identical(crossAxisAlignment, CrossAxisAlignment.baseline) || textBaseline != null, 'textBaseline is required if you specify the crossAxisAlignment with CrossAxisAlignment.baseline');
// Cannot use == in the assert above instead of identical because of https://github.com/dart-lang/language/issues/1811.
@ -4710,6 +4711,9 @@ class Flex extends MultiChildRenderObjectWidget {
/// Defaults to [Clip.none].
final Clip clipBehavior;
/// {@macro flutter.rendering.RenderFlex.spacing}
final double spacing;
bool get _needTextDirection {
switch (direction) {
case Axis.horizontal:
@ -4751,6 +4755,7 @@ class Flex extends MultiChildRenderObjectWidget {
verticalDirection: verticalDirection,
textBaseline: textBaseline,
clipBehavior: clipBehavior,
spacing: spacing,
);
}
@ -4764,7 +4769,8 @@ class Flex extends MultiChildRenderObjectWidget {
..textDirection = getEffectiveTextDirection(context)
..verticalDirection = verticalDirection
..textBaseline = textBaseline
..clipBehavior = clipBehavior;
..clipBehavior = clipBehavior
..spacing = spacing;
}
@override
@ -4777,6 +4783,8 @@ class Flex extends MultiChildRenderObjectWidget {
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
properties.add(EnumProperty<VerticalDirection>('verticalDirection', verticalDirection, defaultValue: VerticalDirection.down));
properties.add(EnumProperty<TextBaseline>('textBaseline', textBaseline, defaultValue: null));
properties.add(EnumProperty<Clip>('clipBehavior', clipBehavior, defaultValue: Clip.none));
properties.add(DoubleProperty('spacing', spacing, defaultValue: 0.0));
}
}
@ -4983,6 +4991,7 @@ class Row extends Flex {
super.textDirection,
super.verticalDirection,
super.textBaseline, // NO DEFAULT: we don't know what the text's baseline should be
super.spacing,
super.children,
}) : super(
direction: Axis.horizontal,
@ -5174,6 +5183,7 @@ class Column extends Flex {
super.textDirection,
super.verticalDirection,
super.textBaseline,
super.spacing,
super.children,
}) : super(
direction: Axis.vertical,

View File

@ -109,6 +109,29 @@ void main() {
expect(flex.getMaxIntrinsicWidth(100.0), equals(0.0));
});
test('Vertical Overflow with RenderFlex.spacing', () {
final RenderConstrainedBox flexible = RenderConstrainedBox(
additionalConstraints: const BoxConstraints.expand(),
);
final RenderFlex flex = RenderFlex(
direction: Axis.vertical,
spacing: 16.0,
children: <RenderBox>[
RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(height: 200.0)),
flexible,
],
);
final FlexParentData flexParentData = flexible.parentData! as FlexParentData;
flexParentData.flex = 1;
const BoxConstraints viewport = BoxConstraints(maxHeight: 100.0, maxWidth: 100.0);
layout(flex, constraints: viewport);
expect(flexible.size.height, equals(0.0));
expect(flex.getMinIntrinsicHeight(100.0), equals(216.0));
expect(flex.getMaxIntrinsicHeight(100.0), equals(216.0));
expect(flex.getMinIntrinsicWidth(100.0), equals(0.0));
expect(flex.getMaxIntrinsicWidth(100.0), equals(0.0));
});
test('Horizontal Overflow', () {
final RenderConstrainedBox flexible = RenderConstrainedBox(
additionalConstraints: const BoxConstraints.expand(),
@ -131,6 +154,29 @@ void main() {
expect(flex.getMaxIntrinsicWidth(100.0), equals(200.0));
});
test('Horizontal Overflow with RenderFlex.spacing', () {
final RenderConstrainedBox flexible = RenderConstrainedBox(
additionalConstraints: const BoxConstraints.expand(),
);
final RenderFlex flex = RenderFlex(
textDirection: TextDirection.ltr,
spacing: 12.0,
children: <RenderBox>[
RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 200.0)),
flexible,
],
);
final FlexParentData flexParentData = flexible.parentData! as FlexParentData;
flexParentData.flex = 1;
const BoxConstraints viewport = BoxConstraints(maxHeight: 100.0, maxWidth: 100.0);
layout(flex, constraints: viewport);
expect(flexible.size.width, equals(0.0));
expect(flex.getMinIntrinsicHeight(100.0), equals(0.0));
expect(flex.getMaxIntrinsicHeight(100.0), equals(0.0));
expect(flex.getMinIntrinsicWidth(100.0), equals(212.0));
expect(flex.getMaxIntrinsicWidth(100.0), equals(212.0));
});
test('Vertical Flipped Constraints', () {
final RenderFlex flex = RenderFlex(
direction: Axis.vertical,
@ -162,7 +208,8 @@ void main() {
' mainAxisAlignment: start\n'
' mainAxisSize: max\n'
' crossAxisAlignment: center\n'
' verticalDirection: down\n',
' verticalDirection: down\n'
' spacing: 0.0\n',
),
);
});
@ -253,6 +300,215 @@ void main() {
expect(box3.size.height, equals(100.0));
});
test('MainAxisAlignment.start with RenderFlex.spacing', () {
final RenderConstrainedBox box1 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box2 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box3 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderFlex flex = RenderFlex(
textDirection: TextDirection.ltr,
spacing: 14.0,
);
flex.addAll(<RenderBox>[box1, box2, box3]);
layout(flex, constraints: const BoxConstraints(
maxWidth: 500.0,
maxHeight: 400.0,
));
Offset getOffset(RenderBox box) {
final FlexParentData parentData = box.parentData! as FlexParentData;
return parentData.offset;
}
expect(getOffset(box1).dx, equals(0.0));
expect(box1.size.width, equals(100.0));
expect(getOffset(box2).dx, equals(114.0));
expect(box2.size.width, equals(100.0));
expect(getOffset(box3).dx, equals(228.0));
expect(box3.size.width, equals(100.0));
flex.direction = Axis.vertical;
pumpFrame();
expect(getOffset(box1).dy, equals(0.0));
expect(box1.size.height, equals(100.0));
expect(getOffset(box2).dy, equals(114.0));
expect(box2.size.height, equals(100.0));
expect(getOffset(box3).dy, equals(228.0));
expect(box3.size.height, equals(100.0));
});
test('MainAxisAlignment.end with RenderFlex.spacing', () {
final RenderConstrainedBox box1 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box2 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box3 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderFlex flex = RenderFlex(
textDirection: TextDirection.ltr,
mainAxisAlignment: MainAxisAlignment.end,
spacing: 14.0,
);
flex.addAll(<RenderBox>[box1, box2, box3]);
layout(flex, constraints: const BoxConstraints(
maxWidth: 500.0,
maxHeight: 400.0,
));
Offset getOffset(RenderBox box) {
final FlexParentData parentData = box.parentData! as FlexParentData;
return parentData.offset;
}
expect(getOffset(box1).dx, equals(172.0));
expect(box1.size.width, equals(100.0));
expect(getOffset(box2).dx, equals(286.0));
expect(box2.size.width, equals(100.0));
expect(getOffset(box3).dx, equals(400.0));
expect(box3.size.width, equals(100.0));
flex.direction = Axis.vertical;
pumpFrame();
expect(getOffset(box1).dy, equals(72.0));
expect(box1.size.height, equals(100.0));
expect(getOffset(box2).dy, equals(186.0));
expect(box2.size.height, equals(100.0));
expect(getOffset(box3).dy, equals(300.0));
expect(box3.size.height, equals(100.0));
});
test('MainAxisAlignment.center with RenderFlex.spacing', () {
final RenderConstrainedBox box1 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box2 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box3 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderFlex flex = RenderFlex(
textDirection: TextDirection.ltr,
mainAxisAlignment: MainAxisAlignment.center,
spacing: 14.0,
);
flex.addAll(<RenderBox>[box1, box2, box3]);
layout(flex, constraints: const BoxConstraints(
maxWidth: 500.0,
maxHeight: 400.0,
));
Offset getOffset(RenderBox box) {
final FlexParentData parentData = box.parentData! as FlexParentData;
return parentData.offset;
}
expect(getOffset(box1).dx, equals(86.0));
expect(box1.size.width, equals(100.0));
expect(getOffset(box2).dx, equals(200.0));
expect(box2.size.width, equals(100.0));
expect(getOffset(box3).dx, equals(314.0));
expect(box3.size.width, equals(100.0));
flex.direction = Axis.vertical;
pumpFrame();
expect(getOffset(box1).dy, equals(36.0));
expect(box1.size.height, equals(100.0));
expect(getOffset(box2).dy, equals(150.0));
expect(box2.size.height, equals(100.0));
expect(getOffset(box3).dy, equals(264.0));
expect(box3.size.height, equals(100.0));
});
test('MainAxisAlignment.spaceEvenly with RenderFlex.spacing', () {
final RenderConstrainedBox box1 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box2 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box3 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderFlex flex = RenderFlex(
textDirection: TextDirection.ltr,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
spacing: 14.0,
);
flex.addAll(<RenderBox>[box1, box2, box3]);
layout(flex, constraints: const BoxConstraints(
maxWidth: 500.0,
maxHeight: 400.0,
));
Offset getOffset(RenderBox box) {
final FlexParentData parentData = box.parentData! as FlexParentData;
return parentData.offset;
}
expect(getOffset(box1).dx, equals(43.0));
expect(box1.size.width, equals(100.0));
expect(getOffset(box2).dx, equals(200.0));
expect(box2.size.width, equals(100.0));
expect(getOffset(box3).dx, equals(357.0));
expect(box3.size.width, equals(100.0));
flex.direction = Axis.vertical;
pumpFrame();
expect(getOffset(box1).dy, equals(18.0));
expect(box1.size.height, equals(100.0));
expect(getOffset(box2).dy, equals(150.0));
expect(box2.size.height, equals(100.0));
expect(getOffset(box3).dy, equals(282.0));
expect(box3.size.height, equals(100.0));
});
test('MainAxisAlignment.spaceAround with RenderFlex.spacing', () {
final RenderConstrainedBox box1 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box2 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box3 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderFlex flex = RenderFlex(
textDirection: TextDirection.ltr,
mainAxisAlignment: MainAxisAlignment.spaceAround,
spacing: 14.0,
);
flex.addAll(<RenderBox>[box1, box2, box3]);
layout(flex, constraints: const BoxConstraints(
maxWidth: 500.0,
maxHeight: 400.0,
));
Offset getOffset(RenderBox box) {
final FlexParentData parentData = box.parentData! as FlexParentData;
return parentData.offset;
}
expect(getOffset(box1).dx, closeTo(28.6, 0.1));
expect(box1.size.width, equals(100.0));
expect(getOffset(box2).dx, equals(200.0));
expect(box2.size.width, equals(100.0));
expect(getOffset(box3).dx, closeTo(371.3, 0.1));
expect(box3.size.width, equals(100.0));
flex.direction = Axis.vertical;
pumpFrame();
expect(getOffset(box1).dy, equals(12.0));
expect(box1.size.height, equals(100.0));
expect(getOffset(box2).dy, equals(150.0));
expect(box2.size.height, equals(100.0));
expect(getOffset(box3).dy, equals(288.0));
expect(box3.size.height, equals(100.0));
});
test('MainAxisAlignment.spaceBetween with RenderFlex.spacing', () {
final RenderConstrainedBox box1 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box2 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box3 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderFlex flex = RenderFlex(
textDirection: TextDirection.ltr,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
spacing: 14.0,
);
flex.addAll(<RenderBox>[box1, box2, box3]);
layout(flex, constraints: const BoxConstraints(
maxWidth: 500.0,
maxHeight: 400.0,
));
Offset getOffset(RenderBox box) {
final FlexParentData parentData = box.parentData! as FlexParentData;
return parentData.offset;
}
expect(getOffset(box1).dx, equals(0.0));
expect(box1.size.width, equals(100.0));
expect(getOffset(box2).dx, equals(200.0));
expect(box2.size.width, equals(100.0));
expect(getOffset(box3).dx, equals(400.0));
expect(box3.size.width, equals(100.0));
flex.direction = Axis.vertical;
pumpFrame();
expect(getOffset(box1).dy, equals(0.0));
expect(box1.size.height, equals(100.0));
expect(getOffset(box2).dy, equals(150.0));
expect(box2.size.height, equals(100.0));
expect(getOffset(box3).dy, equals(300.0));
expect(box3.size.height, equals(100.0));
});
test('Fit.loose', () {
final RenderConstrainedBox box1 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
final RenderConstrainedBox box2 = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 100.0, height: 100.0));
@ -719,6 +975,61 @@ void main() {
expect(flex.getMaxIntrinsicWidth(500.0), 200.0 + 500.0);
});
test('main/cross axis intrinsics in horizontal direction and RenderFlex.spacing', () {
const BoxConstraints square = BoxConstraints.tightFor(width: 100.0, height: 100.0);
final RenderConstrainedBox box1 = RenderConstrainedBox(additionalConstraints: square);
final RenderConstrainedBox box2 = RenderConstrainedBox(additionalConstraints: square);
final RenderConstrainedBox box3 = RenderConstrainedBox(additionalConstraints: square);
final RenderFlex flex = RenderFlex(
textDirection: TextDirection.ltr,
spacing: 16.0,
);
flex.addAll(<RenderBox>[box1, box2, box3]);
expect(flex.getMinIntrinsicWidth(double.infinity), 332.0);
expect(flex.getMaxIntrinsicWidth(double.infinity), 332.0);
expect(flex.getMinIntrinsicHeight(double.infinity), 100.0);
expect(flex.getMaxIntrinsicHeight(double.infinity), 100.0);
expect(flex.getMinIntrinsicWidth(300.0), 332.0);
expect(flex.getMaxIntrinsicWidth(300.0), 332.0);
expect(flex.getMinIntrinsicHeight(300.0), 100.0);
expect(flex.getMaxIntrinsicHeight(300.0), 100.0);
expect(flex.getMinIntrinsicWidth(500.0), 332.0);
expect(flex.getMaxIntrinsicWidth(500.0), 332.0);
expect(flex.getMinIntrinsicHeight(500.0), 100.0);
expect(flex.getMaxIntrinsicHeight(500.0), 100.0);
});
test('main/cross axis intrinsics in vertical direction and RenderFlex.spacing', () {
const BoxConstraints square = BoxConstraints.tightFor(width: 100.0, height: 100.0);
final RenderConstrainedBox box1 = RenderConstrainedBox(additionalConstraints: square);
final RenderConstrainedBox box2 = RenderConstrainedBox(additionalConstraints: square);
final RenderConstrainedBox box3 = RenderConstrainedBox(additionalConstraints: square);
final RenderFlex flex = RenderFlex(
textDirection: TextDirection.ltr,
direction: Axis.vertical,
spacing: 16.0,
);
flex.addAll(<RenderBox>[box1, box2, box3]);
expect(flex.getMinIntrinsicWidth(double.infinity), 100.0);
expect(flex.getMaxIntrinsicWidth(double.infinity), 100.0);
expect(flex.getMinIntrinsicHeight(double.infinity), 332.0);
expect(flex.getMaxIntrinsicHeight(double.infinity), 332.0);
expect(flex.getMinIntrinsicWidth(300.0), 100.0);
expect(flex.getMaxIntrinsicWidth(300.0), 100.0);
expect(flex.getMinIntrinsicHeight(300.0), 332.0);
expect(flex.getMaxIntrinsicHeight(300.0), 332.0);
expect(flex.getMinIntrinsicWidth(500.0), 100.0);
expect(flex.getMaxIntrinsicWidth(500.0), 100.0);
expect(flex.getMinIntrinsicHeight(500.0), 332.0);
expect(flex.getMaxIntrinsicHeight(500.0), 332.0);
});
test('cross axis intrinsics, with ascending flex flow layout', () {
const BoxConstraints square = BoxConstraints.tightFor(width: 5.0, height: 5.0);
// 3 'A's separated by zero-width spaces. Max intrinsic width = 30, min intrinsic width = 10
@ -909,6 +1220,21 @@ void main() {
// ignore: avoid_dynamic_calls
expect(exceptions.first.message, isNot(contains('Null check operator')));
});
test('Negative RenderFlex.spacing throws an exception', () {
final List<dynamic> exceptions = <dynamic>[];
final RenderDecoratedBox box = RenderDecoratedBox(decoration: const BoxDecoration());
try {
RenderFlex(
textDirection: TextDirection.ltr,
spacing: -15.0,
children: <RenderBox>[box],
);
} catch (e) {
exceptions.add(e);
}
expect(exceptions, hasLength(1));
});
}
class RenderFlowBaselineTestBox extends RenderBox {

View File

@ -7,6 +7,41 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
Widget constrainedFlex({
required Axis direction,
required MainAxisAlignment mainAxisAlignment,
required double spacing,
}) {
return Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
width: 300.0,
height: 300.0,
child: Flex(
direction: direction,
mainAxisAlignment: mainAxisAlignment,
spacing: spacing,
children: const <Widget>[
SizedBox(
width: 50.0,
height: 50.0,
),
SizedBox(
width: 50.0,
height: 50.0,
),
SizedBox(
width: 50.0,
height: 50.0,
),
],
),
),
),
);
}
testWidgets('Can hit test flex children of stacks', (WidgetTester tester) async {
bool didReceiveTap = false;
await tester.pumpWidget(
@ -147,4 +182,164 @@ void main() {
const Column();
const Row();
});
testWidgets('Default Flex.spacing value', (WidgetTester tester) async {
await tester.pumpWidget(const Flex(direction: Axis.vertical));
final Flex flex = tester.widget(find.byType(Flex));
expect(flex.spacing, 0.0);
});
testWidgets('Can update Flex.spacing value', (WidgetTester tester) async {
Widget buildFlex({ required double spacing }) {
return Center(
child: Directionality(
textDirection: TextDirection.ltr,
child: Flex(
spacing: spacing,
direction: Axis.vertical,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
height: 100.0,
width: 100.0,
color: const Color(0xFFFF0000),
),
Container(
height: 100.0,
width: 100.0,
color: const Color(0xFF0000FF),
),
Container(
height: 100.0,
width: 100.0,
color: const Color(0xff00FF00),
),
],
),
),
);
}
await tester.pumpWidget(buildFlex(spacing: 8.0));
RenderFlex renderObject = tester.allRenderObjects.whereType<RenderFlex>().first;
expect(renderObject.spacing, equals(8.0));
expect(tester.getSize(find.byType(Flex)).width, equals(100.0));
expect(tester.getSize(find.byType(Flex)).height, equals(316.0));
await tester.pumpWidget(buildFlex(spacing: 18.0));
renderObject = tester.allRenderObjects.whereType<RenderFlex>().first;
expect(renderObject.spacing, equals(18.0));
expect(tester.getSize(find.byType(Flex)).width, equals(100.0));
expect(tester.getSize(find.byType(Flex)).height, equals(336.0));
});
testWidgets('Overconstrained Flex with MainAxisAlignment.start and spacing', (WidgetTester tester) async {
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.start,
spacing: 50.0,
));
// 50.0 * 3 (children) + 50.0 * 2 (spacing) = 250.0 < 300.0 (constraints)
expect(tester.takeException(), isNull);
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.start,
spacing: 100.0,
));
// 50.0 * 3 (children) + 100.0 * 2 (spacing) = 350.0 > 300.0 (constraints)
expect(tester.takeException(), isAssertionError);
});
testWidgets('Overconstrained Flex with MainAxisAlignment.end and spacing', (WidgetTester tester) async {
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.end,
spacing: 50.0,
));
// 50.0 * 3 (children) + 50.0 * 2 (spacing) = 250.0 < 300.0 (constraints)
expect(tester.takeException(), isNull);
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.end,
spacing: 100.0,
));
// 50.0 * 3 (children) + 100.0 * 2 (spacing) = 350.0 > 300.0 (constraints)
expect(tester.takeException(), isAssertionError);
});
testWidgets('Overconstrained Flex with MainAxisAlignment.center and spacing', (WidgetTester tester) async {
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.center,
spacing: 50.0,
));
// 50.0 * 3 (children) + 50.0 * 2 (spacing) = 250.0 < 300.0 (constraints)
expect(tester.takeException(), isNull);
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.center,
spacing: 100.0,
));
// 50.0 * 3 (children) + 100.0 * 2 (spacing) = 350.0 > 300.0 (constraints)
expect(tester.takeException(), isAssertionError);
});
testWidgets('Overconstrained Flex with MainAxisAlignment.spaceAround and spacing', (WidgetTester tester) async {
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.spaceAround,
spacing: 50.0,
));
// 50.0 * 3 (children) + 50.0 * 2 (spacing) = 250.0 < 300.0 (constraints)
expect(tester.takeException(), isNull);
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.spaceAround,
spacing: 100.0,
));
// 50.0 * 3 (children) + 100.0 * 2 (spacing) = 350.0 > 300.0 (constraints)
expect(tester.takeException(), isAssertionError);
});
testWidgets('Overconstrained Flex with MainAxisAlignment.spaceEvenly and spacing', (WidgetTester tester) async {
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
spacing: 50.0,
));
// 50.0 * 3 (children) + 50.0 * 2 (spacing) = 250.0 < 300.0 (constraints)
expect(tester.takeException(), isNull);
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
spacing: 100.0,
));
// 50.0 * 3 (children) + 100.0 * 2 (spacing) = 350.0 > 300.0 (constraints)
expect(tester.takeException(), isAssertionError);
});
testWidgets('Overconstrained Flex with MainAxisAlignment.spaceBetween and spacing', (WidgetTester tester) async {
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
spacing: 50.0,
));
// 50.0 * 3 (children) + 50.0 * 2 (spacing) = 250.0 < 300.0 (constraints)
expect(tester.takeException(), isNull);
await tester.pumpWidget(constrainedFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
spacing: 100.0,
));
// 50.0 * 3 (children) + 100.0 * 2 (spacing) = 350.0 > 300.0 (constraints)
expect(tester.takeException(), isAssertionError);
});
}

View File

@ -278,6 +278,7 @@ void main() {
' crossAxisAlignment: center',
' textDirection: ltr',
' verticalDirection: down',
' spacing: 0.0',
'◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤',
'════════════════════════════════════════════════════════════════════════════════════════════════════',
'',