Skip to content

Commit dc331d3

Browse files
[RenderAnimatedSize] Resume interrupted resizing animation on attach (#100519)
1 parent 74f08c7 commit dc331d3

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

packages/flutter/lib/src/rendering/animated_size.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,22 @@ class RenderAnimatedSize extends RenderAligningShiftedBox {
174174
_controller.resync(vsync);
175175
}
176176

177+
@override
178+
void attach(PipelineOwner owner) {
179+
super.attach(owner);
180+
switch (state) {
181+
case RenderAnimatedSizeState.start:
182+
case RenderAnimatedSizeState.stable:
183+
break;
184+
case RenderAnimatedSizeState.changed:
185+
case RenderAnimatedSizeState.unstable:
186+
// Call markNeedsLayout in case the RenderObject isn't marked dirty
187+
// already, to resume interrupted resizing animation.
188+
markNeedsLayout();
189+
break;
190+
}
191+
}
192+
177193
@override
178194
void detach() {
179195
_controller.stop();

packages/flutter/lib/src/widgets/single_child_scroll_view.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,12 @@ class _RenderSingleChildViewport extends RenderBox with RenderObjectWithChildMix
678678
);
679679
}
680680

681+
@override
682+
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
683+
super.debugFillProperties(properties);
684+
properties.add(DiagnosticsProperty<Offset>('offset', _paintOffset));
685+
}
686+
681687
@override
682688
Rect describeSemanticsClip(RenderObject child) {
683689
assert(axis != null);

packages/flutter/test/widgets/animated_size_test.dart

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,5 +349,89 @@ void main() {
349349
await pumpWidget(const Size(222, 222), const Duration(milliseconds: 10));
350350
expect(tester.renderObject<RenderBox>(find.byType(IntrinsicHeight)).size, const Size(222, 222));
351351
});
352+
353+
testWidgets('re-attach with interrupted animation', (WidgetTester tester) async {
354+
const Key key1 = ValueKey<String>('key1');
355+
const Key key2 = ValueKey<String>('key2');
356+
late StateSetter setState;
357+
Size childSize = const Size.square(100);
358+
final Widget animatedSize = Center(
359+
key: GlobalKey(debugLabel: 'animated size'),
360+
// This SizedBox creates a relayout boundary so _cleanRelayoutBoundary
361+
// does not mark the descendant render objects below the relayout boundary
362+
// dirty.
363+
child: SizedBox.fromSize(
364+
size: const Size.square(200),
365+
child: Center(
366+
child: AnimatedSize(
367+
duration: const Duration(seconds: 1),
368+
child: StatefulBuilder(
369+
builder: (BuildContext context, StateSetter stateSetter) {
370+
setState = stateSetter;
371+
return SizedBox.fromSize(size: childSize);
372+
},
373+
),
374+
),
375+
),
376+
),
377+
);
378+
379+
await tester.pumpWidget(
380+
Directionality(
381+
textDirection: TextDirection.ltr,
382+
child: Row(
383+
children: <Widget>[
384+
SizedBox(
385+
key: key1,
386+
height: 200,
387+
child: animatedSize,
388+
),
389+
const SizedBox(
390+
key: key2,
391+
height: 200,
392+
)
393+
],
394+
),
395+
)
396+
);
397+
398+
setState(() {
399+
childSize = const Size.square(150);
400+
});
401+
// Kick off the resizing animation.
402+
await tester.pump();
403+
404+
// Immediately reparent the AnimatedSize subtree to a different parent
405+
// with the same incoming constraints.
406+
await tester.pumpWidget(
407+
Directionality(
408+
textDirection: TextDirection.ltr,
409+
child: Row(
410+
children: <Widget>[
411+
const SizedBox(
412+
key: key1,
413+
height: 200,
414+
),
415+
SizedBox(
416+
key: key2,
417+
height: 200,
418+
child: animatedSize,
419+
)
420+
],
421+
),
422+
)
423+
);
424+
425+
expect(
426+
tester.renderObject<RenderBox>(find.byType(AnimatedSize)).size,
427+
const Size.square(100),
428+
);
429+
await tester.pumpAndSettle();
430+
// The animatedSize widget animates to the right size.
431+
expect(
432+
tester.renderObject<RenderBox>(find.byType(AnimatedSize)).size,
433+
const Size.square(150),
434+
);
435+
});
352436
});
353437
}

0 commit comments

Comments
 (0)