diff --git a/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart b/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart index a0658cc63e2030dea8b5c59d957e1b201af46020..b3ff11de63f7345cda1185a03b088a38340813a3 100644 --- a/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart +++ b/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart @@ -663,6 +663,10 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> { @override void didUpdateWidget(covariant DraggableScrollableSheet oldWidget) { super.didUpdateWidget(oldWidget); + if (widget.controller != oldWidget.controller) { + oldWidget.controller?._detach(); + widget.controller?._attach(_scrollController); + } _replaceExtent(oldWidget); } @@ -715,7 +719,9 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> { _scrollController.extent = _extent; // If an external facing controller was provided, let it know that the // extent has been replaced. - widget.controller?._onExtentReplaced(previousExtent); + if (widget.controller == oldWidget.controller) { + widget.controller?._onExtentReplaced(previousExtent); + } if (widget.snap && (widget.snap != oldWidget.snap || widget.snapSizes != oldWidget.snapSizes) && _scrollController.hasClients diff --git a/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart b/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart index 2f4d735902d153f7c323676818061084ef345836..44302da0e86a628f68be681e47ee8d31e38a0389 100644 --- a/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart +++ b/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart @@ -1502,4 +1502,48 @@ void main() { // DraggableScrollableSheet has rebuilt, so expect the builder to be called. expect(buildCount, 2); }); + + testWidgets('DraggableScrollableSheet controller can be changed', (WidgetTester tester) async { + final DraggableScrollableController controller1 = DraggableScrollableController(); + final DraggableScrollableController controller2 = DraggableScrollableController(); + DraggableScrollableController controller = controller1; + await tester.pumpWidget(MaterialApp( + home: StatefulBuilder( + builder: (BuildContext context, StateSetter setState) => Scaffold( + body: DraggableScrollableSheet( + initialChildSize: 0.25, + snap: true, + snapSizes: const <double>[0.25, 0.5, 1.0], + controller: controller, + builder: (BuildContext context, ScrollController scrollController) { + return ListView( + controller: scrollController, + children: <Widget>[ + ElevatedButton( + onPressed: () => setState(() { + controller = controller2; + }), + child: const Text('Switch controller'), + ), + Container( + height: 10000, + color: Colors.blue, + ), + ], + ); + }, + ), + ), + ), + )); + + expect(controller1.isAttached, true); + expect(controller2.isAttached, false); + + await tester.tap(find.text('Switch controller')); + await tester.pump(); + + expect(controller1.isAttached, false); + expect(controller2.isAttached, true); + }); }