Fix compute intrinsic size for wrap (#55469)
diff --git a/AUTHORS b/AUTHORS
index 901b250..4c673d6 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -54,3 +54,4 @@
Michel Feinstein <michel@feinstein.com.br>
Michael Lee <ckmichael8@gmail.com>
Katarina Sheremet <katarina@sheremet.ch>
+Mikhail Zotyev <mbixjkee1392@gmail.com>
diff --git a/packages/flutter/lib/src/rendering/wrap.dart b/packages/flutter/lib/src/rendering/wrap.dart
index 30cdc10..c1bb0d7 100644
--- a/packages/flutter/lib/src/rendering/wrap.dart
+++ b/packages/flutter/lib/src/rendering/wrap.dart
@@ -383,7 +383,6 @@
double _computeIntrinsicHeightForWidth(double width) {
assert(direction == Axis.horizontal);
- int runCount = 0;
double height = 0.0;
double runWidth = 0.0;
double runHeight = 0.0;
@@ -392,11 +391,9 @@
while (child != null) {
final double childWidth = child.getMaxIntrinsicWidth(double.infinity);
final double childHeight = child.getMaxIntrinsicHeight(childWidth);
- if (runWidth + childWidth > width) {
- height += runHeight;
- if (runCount > 0)
- height += runSpacing;
- runCount += 1;
+ // There must be at least one child before we move on to the next run.
+ if (childCount > 0 && runWidth + childWidth + spacing > width) {
+ height += runHeight + runSpacing;
runWidth = 0.0;
runHeight = 0.0;
childCount = 0;
@@ -408,14 +405,12 @@
childCount += 1;
child = childAfter(child);
}
- if (childCount > 0)
- height += runHeight + runSpacing;
+ height += runHeight;
return height;
}
double _computeIntrinsicWidthForHeight(double height) {
assert(direction == Axis.vertical);
- int runCount = 0;
double width = 0.0;
double runHeight = 0.0;
double runWidth = 0.0;
@@ -424,11 +419,9 @@
while (child != null) {
final double childHeight = child.getMaxIntrinsicHeight(double.infinity);
final double childWidth = child.getMaxIntrinsicWidth(childHeight);
- if (runHeight + childHeight > height) {
- width += runWidth;
- if (runCount > 0)
- width += runSpacing;
- runCount += 1;
+ // There must be at least one child before we move on to the next run.
+ if (childCount > 0 && runHeight + childHeight + spacing > height) {
+ width += runWidth + runSpacing;
runHeight = 0.0;
runWidth = 0.0;
childCount = 0;
@@ -440,8 +433,7 @@
childCount += 1;
child = childAfter(child);
}
- if (childCount > 0)
- width += runWidth + runSpacing;
+ width += runWidth;
return width;
}
diff --git a/packages/flutter/test/rendering/wrap_test.dart b/packages/flutter/test/rendering/wrap_test.dart
index 57d2210..e6dac87 100644
--- a/packages/flutter/test/rendering/wrap_test.dart
+++ b/packages/flutter/test/rendering/wrap_test.dart
@@ -25,4 +25,130 @@
),
);
});
+
+ test('Compute intrinsic height test', () {
+ final List<RenderBox> children = <RenderBox>[
+ RenderConstrainedBox(
+ additionalConstraints: const BoxConstraints(
+ minWidth: 80,
+ minHeight: 80,
+ ),
+ ),
+ RenderConstrainedBox(
+ additionalConstraints: const BoxConstraints(
+ minWidth: 80,
+ minHeight: 80,
+ ),
+ ),
+ RenderConstrainedBox(
+ additionalConstraints: const BoxConstraints(
+ minWidth: 80,
+ minHeight: 80,
+ ),
+ ),
+ ];
+
+ final RenderWrap renderWrap = RenderWrap();
+
+ children.forEach(renderWrap.add);
+
+ renderWrap.spacing = 5;
+ renderWrap.runSpacing = 5;
+ renderWrap.direction = Axis.horizontal;
+
+ expect(renderWrap.computeMaxIntrinsicHeight(245), 165);
+ expect(renderWrap.computeMaxIntrinsicHeight(250), 80);
+ expect(renderWrap.computeMaxIntrinsicHeight(80), 250);
+ expect(renderWrap.computeMaxIntrinsicHeight(79), 250);
+ expect(renderWrap.computeMinIntrinsicHeight(245), 165);
+ expect(renderWrap.computeMinIntrinsicHeight(250), 80);
+ expect(renderWrap.computeMinIntrinsicHeight(80), 250);
+ expect(renderWrap.computeMinIntrinsicHeight(79), 250);
+ });
+
+ test('Compute intrinsic width test', () {
+ final List<RenderBox> children = <RenderBox>[
+ RenderConstrainedBox(
+ additionalConstraints: const BoxConstraints(
+ minWidth: 80,
+ minHeight: 80,
+ ),
+ ),
+ RenderConstrainedBox(
+ additionalConstraints: const BoxConstraints(
+ minWidth: 80,
+ minHeight: 80,
+ ),
+ ),
+ RenderConstrainedBox(
+ additionalConstraints: const BoxConstraints(
+ minWidth: 80,
+ minHeight: 80,
+ ),
+ ),
+ ];
+
+ final RenderWrap renderWrap = RenderWrap();
+
+ children.forEach(renderWrap.add);
+
+ renderWrap.spacing = 5;
+ renderWrap.runSpacing = 5;
+ renderWrap.direction = Axis.vertical;
+
+ expect(renderWrap.computeMaxIntrinsicWidth(245), 165);
+ expect(renderWrap.computeMaxIntrinsicWidth(250), 80);
+ expect(renderWrap.computeMaxIntrinsicWidth(80), 250);
+ expect(renderWrap.computeMaxIntrinsicWidth(79), 250);
+ expect(renderWrap.computeMinIntrinsicWidth(245), 165);
+ expect(renderWrap.computeMinIntrinsicWidth(250), 80);
+ expect(renderWrap.computeMinIntrinsicWidth(80), 250);
+ expect(renderWrap.computeMinIntrinsicWidth(79), 250);
+ });
+
+ test('Compute intrinsic height for only one run', () {
+ final RenderBox child = RenderConstrainedBox(
+ additionalConstraints: const BoxConstraints(
+ minWidth: 80,
+ minHeight: 80,
+ ),
+ );
+
+ final RenderWrap renderWrap = RenderWrap();
+ renderWrap.add(child);
+
+ renderWrap.spacing = 5;
+ renderWrap.runSpacing = 5;
+ renderWrap.direction = Axis.horizontal;
+
+ expect(renderWrap.computeMaxIntrinsicHeight(100), 80);
+ expect(renderWrap.computeMaxIntrinsicHeight(79), 80);
+ expect(renderWrap.computeMaxIntrinsicHeight(80), 80);
+ expect(renderWrap.computeMinIntrinsicHeight(100), 80);
+ expect(renderWrap.computeMinIntrinsicHeight(79), 80);
+ expect(renderWrap.computeMinIntrinsicHeight(80), 80);
+ });
+
+ test('Compute intrinsic width for only one run', () {
+ final RenderBox child = RenderConstrainedBox(
+ additionalConstraints: const BoxConstraints(
+ minWidth: 80,
+ minHeight: 80,
+ ),
+ );
+
+ final RenderWrap renderWrap = RenderWrap();
+ renderWrap.add(child);
+
+ renderWrap.spacing = 5;
+ renderWrap.runSpacing = 5;
+ renderWrap.direction = Axis.vertical;
+
+ expect(renderWrap.computeMaxIntrinsicWidth(100), 80);
+ expect(renderWrap.computeMaxIntrinsicWidth(79), 80);
+ expect(renderWrap.computeMaxIntrinsicWidth(80), 80);
+ expect(renderWrap.computeMinIntrinsicWidth(100), 80);
+ expect(renderWrap.computeMinIntrinsicWidth(79), 80);
+ expect(renderWrap.computeMinIntrinsicWidth(80), 80);
+ });
}