Unverified Commit 96d330a2 authored by Christopher Fujino's avatar Christopher Fujino Committed by GitHub

Revert "Revert "Implement dryLayout for RenderAnimatedSize (#71097)" (#71180)" (#71185)

This reverts commit 358f9b0e.
parent 358f9b0e
...@@ -223,6 +223,38 @@ class RenderAnimatedSize extends RenderAligningShiftedBox { ...@@ -223,6 +223,38 @@ class RenderAnimatedSize extends RenderAligningShiftedBox {
_hasVisualOverflow = true; _hasVisualOverflow = true;
} }
@override
Size computeDryLayout(BoxConstraints constraints) {
if (child == null || constraints.isTight) {
return constraints.smallest;
}
// This simplified version of performLayout only calculates the current
// size without modifying global state. See performLayout for comments
// explaining the rational behind the implementation.
final Size childSize = child!.getDryLayout(constraints);
assert(_state != null);
switch (_state) {
case RenderAnimatedSizeState.start:
return constraints.constrain(childSize);
case RenderAnimatedSizeState.stable:
if (_sizeTween.end != childSize) {
return constraints.constrain(size);
} else if (_controller.value == _controller.upperBound) {
return constraints.constrain(childSize);
}
break;
case RenderAnimatedSizeState.unstable:
case RenderAnimatedSizeState.changed:
if (_sizeTween.end != childSize) {
return constraints.constrain(childSize);
}
break;
}
return constraints.constrain(_animatedSize!);
}
void _restartAnimation() { void _restartAnimation() {
_lastValue = 0.0; _lastValue = 0.0;
_controller.forward(from: 0.0); _controller.forward(from: 0.0);
......
...@@ -1769,6 +1769,7 @@ abstract class RenderBox extends RenderObject { ...@@ -1769,6 +1769,7 @@ abstract class RenderBox extends RenderObject {
} }
Map<BoxConstraints, Size>? _cachedDryLayoutSizes; Map<BoxConstraints, Size>? _cachedDryLayoutSizes;
bool _computingThisDryLayout = false;
/// Returns the [Size] that this [RenderBox] would like to be given the /// Returns the [Size] that this [RenderBox] would like to be given the
/// provided [BoxConstraints]. /// provided [BoxConstraints].
...@@ -1800,9 +1801,24 @@ abstract class RenderBox extends RenderObject { ...@@ -1800,9 +1801,24 @@ abstract class RenderBox extends RenderObject {
}()); }());
if (shouldCache) { if (shouldCache) {
_cachedDryLayoutSizes ??= <BoxConstraints, Size>{}; _cachedDryLayoutSizes ??= <BoxConstraints, Size>{};
return _cachedDryLayoutSizes!.putIfAbsent(constraints, () => computeDryLayout(constraints)); return _cachedDryLayoutSizes!.putIfAbsent(constraints, () => _computeDryLayout(constraints));
} }
return computeDryLayout(constraints); return _computeDryLayout(constraints);
}
Size _computeDryLayout(BoxConstraints constraints) {
assert(() {
assert(!_computingThisDryLayout);
_computingThisDryLayout = true;
return true;
}());
final Size result = computeDryLayout(constraints);
assert(() {
assert(_computingThisDryLayout);
_computingThisDryLayout = false;
return true;
}());
return result;
} }
/// Computes the value returned by [getDryLayout]. Do not call this /// Computes the value returned by [getDryLayout]. Do not call this
...@@ -1907,7 +1923,7 @@ abstract class RenderBox extends RenderObject { ...@@ -1907,7 +1923,7 @@ abstract class RenderBox extends RenderObject {
assert(_size._owner == this); assert(_size._owner == this);
if (RenderObject.debugActiveLayout != null) { if (RenderObject.debugActiveLayout != null) {
assert( assert(
debugDoingThisResize || debugDoingThisLayout || debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout ||
(RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent), (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent),
'RenderBox.size accessed beyond the scope of resize, layout, or ' 'RenderBox.size accessed beyond the scope of resize, layout, or '
'permitted parent access. RenderBox can always access its own size, ' 'permitted parent access. RenderBox can always access its own size, '
......
...@@ -315,5 +315,53 @@ void main() { ...@@ -315,5 +315,53 @@ void main() {
expect(renderObject.clipBehavior, clip); expect(renderObject.clipBehavior, clip);
} }
}); });
testWidgets('works wrapped in IntrinsicHeight and Wrap', (WidgetTester tester) async {
Future<void> pumpWidget(Size size, [Duration? duration]) async {
return tester.pumpWidget(
Center(
child: IntrinsicHeight(
child: Wrap(
textDirection: TextDirection.ltr,
children: <Widget>[
AnimatedSize(
duration: const Duration(milliseconds: 200),
curve: Curves.easeInOutBack,
vsync: tester,
child: SizedBox(
width: size.width,
height: size.height,
),
),
],
),
),
),
duration,
);
}
await pumpWidget(const Size(100, 100));
expect(tester.renderObject<RenderBox>(find.byType(IntrinsicHeight)).size, const Size(100, 100));
await pumpWidget(const Size(150, 200));
expect(tester.renderObject<RenderBox>(find.byType(IntrinsicHeight)).size, const Size(100, 100));
// Each pump triggers verification of dry layout.
for (int total = 0; total < 200; total += 10) {
await tester.pump(const Duration(milliseconds: 10));
}
expect(tester.renderObject<RenderBox>(find.byType(IntrinsicHeight)).size, const Size(150, 200));
// Change every pump
await pumpWidget(const Size(100, 100));
expect(tester.renderObject<RenderBox>(find.byType(IntrinsicHeight)).size, const Size(150, 200));
await pumpWidget(const Size(111, 111), const Duration(milliseconds: 10));
expect(tester.renderObject<RenderBox>(find.byType(IntrinsicHeight)).size, const Size(111, 111));
await pumpWidget(const Size(222, 222), const Duration(milliseconds: 10));
expect(tester.renderObject<RenderBox>(find.byType(IntrinsicHeight)).size, const Size(222, 222));
});
}); });
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment