diff --git a/packages/flutter/lib/src/widgets/dismissible.dart b/packages/flutter/lib/src/widgets/dismissible.dart index 5e4f02defc..08f28c4acb 100644 --- a/packages/flutter/lib/src/widgets/dismissible.dart +++ b/packages/flutter/lib/src/widgets/dismissible.dart @@ -323,6 +323,8 @@ class _DismissibleState extends State with TickerProviderStateMixin Size? _sizePriorToCollapse; bool _dismissThresholdReached = false; + final GlobalKey _contentKey = GlobalKey(); + @override bool get wantKeepAlive => (_moveController?.isAnimating ?? false) || (_resizeController?.isAnimating ?? false); @@ -668,7 +670,7 @@ class _DismissibleState extends State with TickerProviderStateMixin Widget content = SlideTransition( position: _moveAnimation, - child: widget.child, + child: KeyedSubtree(key: _contentKey, child: widget.child), ); if (background != null) { diff --git a/packages/flutter/test/material/debug_test.dart b/packages/flutter/test/material/debug_test.dart index fb3a221c5f..5d659fbed0 100644 --- a/packages/flutter/test/material/debug_test.dart +++ b/packages/flutter/test/material/debug_test.dart @@ -329,6 +329,7 @@ void main() { ' PhysicalModel\n' ' AnimatedPhysicalModel\n' ' Material\n' + ' KeyedSubtree-[GlobalKey#00000]\n' ' FractionalTranslation\n' ' SlideTransition\n' ' Listener\n' diff --git a/packages/flutter/test/widgets/dismissible_test.dart b/packages/flutter/test/widgets/dismissible_test.dart index 759a65b39e..c8a68eaf60 100644 --- a/packages/flutter/test/widgets/dismissible_test.dart +++ b/packages/flutter/test/widgets/dismissible_test.dart @@ -1150,4 +1150,32 @@ void main() { expect(reportedDismissUpdatePreviousReached, false); expect(reportedDismissUpdateProgress, 0.0); }); + + testWidgets('Change direction does not lose child state', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/108961 + Widget buildFrame(DismissDirection direction) { + return Directionality( + textDirection: TextDirection.ltr, + child: Dismissible( + dragStartBehavior: DragStartBehavior.down, + direction: direction, + key: const Key('Dismissible'), + resizeDuration: null, + child: const SizedBox( + width: 100.0, + height: 100.0, + child: Text('I Love Flutter!'), + ), + ), + ); + } + + await tester.pumpWidget(buildFrame(DismissDirection.horizontal)); + final RenderBox textRenderObjectBegin = tester.renderObject(find.text('I Love Flutter!')); + + await tester.pumpWidget(buildFrame(DismissDirection.none)); + final RenderBox textRenderObjectEnd = tester.renderObject(find.text('I Love Flutter!')); + + expect(identical(textRenderObjectBegin, textRenderObjectEnd), true); + }); }