Implement dryLayout for RenderAnimatedSize (#71097)
This commit is contained in:
parent
13ce828e32
commit
b18f1b81fe
@ -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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
}());
|
}());
|
||||||
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 {
|
|||||||
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() {
|
|||||||
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));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user