[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:
parent
173bf86b7b
commit
00ef750d28
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -278,6 +278,7 @@ void main() {
|
||||
' crossAxisAlignment: center',
|
||||
' textDirection: ltr',
|
||||
' verticalDirection: down',
|
||||
' spacing: 0.0',
|
||||
'◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤',
|
||||
'════════════════════════════════════════════════════════════════════════════════════════════════════',
|
||||
'',
|
||||
|
Loading…
x
Reference in New Issue
Block a user