Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit bc7d3bb

Browse files
authored
Fix DraggableScrollableController.animateTo leaks Ticker (#102504)
1 parent 646b910 commit bc7d3bb

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ typedef ScrollableWidgetBuilder = Widget Function(
5252
/// constraints provided to an attached sheet change.
5353
class DraggableScrollableController extends ChangeNotifier {
5454
_DraggableScrollableSheetScrollController? _attachedController;
55+
final Set<AnimationController> _animationControllers = <AnimationController>{};
5556

5657
/// Get the current size (as a fraction of the parent height) of the attached sheet.
5758
double get size {
@@ -115,6 +116,7 @@ class DraggableScrollableController extends ChangeNotifier {
115116
vsync: _attachedController!.position.context.vsync,
116117
value: _attachedController!.extent.currentSize,
117118
);
119+
_animationControllers.add(animationController);
118120
_attachedController!.position.goIdle();
119121
// This disables any snapping until the next user interaction with the sheet.
120122
_attachedController!.extent.hasDragged = false;
@@ -175,6 +177,7 @@ class DraggableScrollableController extends ChangeNotifier {
175177
assert(_attachedController == null, 'Draggable scrollable controller is already attached to a sheet.');
176178
_attachedController = scrollController;
177179
_attachedController!.extent._currentSize.addListener(notifyListeners);
180+
_attachedController!.onPositionDetached = _disposeAnimationControllers;
178181
}
179182

180183
void _onExtentReplaced(_DraggableSheetExtent previousExtent) {
@@ -193,6 +196,13 @@ class DraggableScrollableController extends ChangeNotifier {
193196
_attachedController?.extent._currentSize.removeListener(notifyListeners);
194197
_attachedController = null;
195198
}
199+
200+
void _disposeAnimationControllers() {
201+
for (final AnimationController animationController in _animationControllers) {
202+
animationController.dispose();
203+
}
204+
_animationControllers.clear();
205+
}
196206
}
197207

198208
/// A container for a [Scrollable] that responds to drag gestures by resizing
@@ -724,6 +734,7 @@ class _DraggableScrollableSheetScrollController extends ScrollController {
724734
}) : assert(extent != null);
725735

726736
_DraggableSheetExtent extent;
737+
VoidCallback? onPositionDetached;
727738

728739
@override
729740
_DraggableScrollableSheetScrollPosition createScrollPosition(
@@ -764,6 +775,12 @@ class _DraggableScrollableSheetScrollController extends ScrollController {
764775
}
765776
extent.updateSize(extent.initialSize, position.context.notificationContext!);
766777
}
778+
779+
@override
780+
void detach(ScrollPosition position) {
781+
onPositionDetached?.call();
782+
super.detach(position);
783+
}
767784
}
768785

769786
/// A scroll position that manages scroll activities for

packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,4 +1209,19 @@ void main() {
12091209
expect(controller.isAttached, true);
12101210
expect(controller.size, isNotNull);
12111211
});
1212+
1213+
testWidgets('DraggableScrollableController.animateTo should not leak Ticker', (WidgetTester tester) async {
1214+
// Regression test for https://github.com/flutter/flutter/issues/102483
1215+
final DraggableScrollableController controller = DraggableScrollableController();
1216+
await tester.pumpWidget(_boilerplate(() {}, controller: controller));
1217+
1218+
controller.animateTo(0.0, curve: Curves.linear, duration: const Duration(milliseconds: 200));
1219+
await tester.pump();
1220+
1221+
// Dispose the DraggableScrollableSheet
1222+
await tester.pumpWidget(const SizedBox.shrink());
1223+
// Controller should be detached and no exception should be thrown
1224+
expect(controller.isAttached, false);
1225+
expect(tester.takeException(), isNull);
1226+
});
12121227
}

0 commit comments

Comments
 (0)