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 {
_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() {
_lastValue = 0.0;
_controller.forward(from: 0.0);
......
......@@ -1769,6 +1769,7 @@ abstract class RenderBox extends RenderObject {
}
Map<BoxConstraints, Size>? _cachedDryLayoutSizes;
bool _computingThisDryLayout = false;
/// Returns the [Size] that this [RenderBox] would like to be given the
/// provided [BoxConstraints].
......@@ -1800,9 +1801,24 @@ abstract class RenderBox extends RenderObject {
}());
if (shouldCache) {
_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
......@@ -1907,7 +1923,7 @@ abstract class RenderBox extends RenderObject {
assert(_size._owner == this);
if (RenderObject.debugActiveLayout != null) {
assert(
debugDoingThisResize || debugDoingThisLayout ||
debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout ||
(RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent),
'RenderBox.size accessed beyond the scope of resize, layout, or '
'permitted parent access. RenderBox can always access its own size, '
......
......@@ -315,5 +315,53 @@ void main() {
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