diff --git a/packages/flutter/lib/src/material/range_slider.dart b/packages/flutter/lib/src/material/range_slider.dart index 9496174caeb..31ca2db1672 100644 --- a/packages/flutter/lib/src/material/range_slider.dart +++ b/packages/flutter/lib/src/material/range_slider.dart @@ -889,9 +889,9 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix static const Duration _minimumInteractionTime = Duration(milliseconds: 500); final _RangeSliderState _state; - late Animation _overlayAnimation; - late Animation _valueIndicatorAnimation; - late Animation _enableAnimation; + late CurvedAnimation _overlayAnimation; + late CurvedAnimation _valueIndicatorAnimation; + late CurvedAnimation _enableAnimation; final TextPainter _startLabelPainter = TextPainter(); final TextPainter _endLabelPainter = TextPainter(); late HorizontalDragGestureRecognizer _drag; @@ -1185,6 +1185,9 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix _tap.dispose(); _startLabelPainter.dispose(); _endLabelPainter.dispose(); + _enableAnimation.dispose(); + _valueIndicatorAnimation.dispose(); + _overlayAnimation.dispose(); super.dispose(); } diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart index 3d8680e634f..cdc6c02cf74 100644 --- a/packages/flutter/lib/src/material/scaffold.dart +++ b/packages/flutter/lib/src/material/scaffold.dart @@ -1322,11 +1322,11 @@ class _FloatingActionButtonTransitionState extends State<_FloatingActionButtonTr // Controls the previous widget.child as it exits. late AnimationController _previousController; late Animation _previousScaleAnimation; - late Animation _previousRotationAnimation; + late TrainHoppingAnimation _previousRotationAnimation; // The animations to run, considering the widget's fabMoveAnimation and the current/previous entrance/exit animations. late Animation _currentScaleAnimation; late Animation _extendedCurrentScaleAnimation; - late Animation _currentRotationAnimation; + late TrainHoppingAnimation _currentRotationAnimation; Widget? _previousChild; @override @@ -1353,6 +1353,7 @@ class _FloatingActionButtonTransitionState extends State<_FloatingActionButtonTr @override void dispose() { _previousController.dispose(); + _disposeAnimations(); super.dispose(); } @@ -1360,6 +1361,7 @@ class _FloatingActionButtonTransitionState extends State<_FloatingActionButtonTr void didUpdateWidget(_FloatingActionButtonTransition oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.fabMotionAnimator != widget.fabMotionAnimator || oldWidget.fabMoveAnimation != widget.fabMoveAnimation) { + _disposeAnimations(); // Get the right scale and rotation animations to use for this widget. _updateAnimations(); } @@ -1395,6 +1397,11 @@ class _FloatingActionButtonTransitionState extends State<_FloatingActionButtonTr end: 1.0, ).chain(CurveTween(curve: Curves.easeIn)); + void _disposeAnimations() { + _previousRotationAnimation.dispose(); + _currentRotationAnimation.dispose(); + } + void _updateAnimations() { // Get the animations for exit and entrance. final CurvedAnimation previousExitScaleAnimation = CurvedAnimation( diff --git a/packages/flutter/lib/src/widgets/overscroll_indicator.dart b/packages/flutter/lib/src/widgets/overscroll_indicator.dart index 42025034069..37f96e3ff72 100644 --- a/packages/flutter/lib/src/widgets/overscroll_indicator.dart +++ b/packages/flutter/lib/src/widgets/overscroll_indicator.dart @@ -812,15 +812,16 @@ class _StretchController extends ChangeNotifier { } _stretchController = AnimationController(vsync: vsync) ..addStatusListener(_changePhase); - final Animation decelerator = CurvedAnimation( + _decelerator = CurvedAnimation( parent: _stretchController, curve: Curves.decelerate, )..addListener(notifyListeners); - _stretchSize = decelerator.drive(_stretchSizeTween); + _stretchSize = _decelerator.drive(_stretchSizeTween); } late final AnimationController _stretchController; late final Animation _stretchSize; + late final CurvedAnimation _decelerator; final Tween _stretchSizeTween = Tween(begin: 0.0, end: 0.0); _StretchState _state = _StretchState.idle; @@ -923,6 +924,7 @@ class _StretchController extends ChangeNotifier { @override void dispose() { _stretchController.dispose(); + _decelerator.dispose(); super.dispose(); } diff --git a/packages/flutter/test/animation/live_binding_test.dart b/packages/flutter/test/animation/live_binding_test.dart index 33692e66eed..197175e5aa7 100644 --- a/packages/flutter/test/animation/live_binding_test.dart +++ b/packages/flutter/test/animation/live_binding_test.dart @@ -9,7 +9,6 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { /* @@ -78,10 +77,7 @@ void main() { // Currently skipped due to daily flake: https://github.com/flutter/flutter/issues/87588 }, skip: true); // Typically skip: isBrowser https://github.com/flutter/flutter/issues/42767 - testWidgets('Should show event indicator for pointer events with setSurfaceSize', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('Should show event indicator for pointer events with setSurfaceSize', (WidgetTester tester) async { final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(200, 200), allLayers: true); addTearDown(animationSheet.dispose); final List taps = []; diff --git a/packages/flutter/test/cupertino/refresh_test.dart b/packages/flutter/test/cupertino/refresh_test.dart index fb66030fe7d..5601753a471 100644 --- a/packages/flutter/test/cupertino/refresh_test.dart +++ b/packages/flutter/test/cupertino/refresh_test.dart @@ -10,7 +10,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { late FakeBuilder mockHelper; @@ -35,10 +34,7 @@ void main() { } void uiTestGroup() { - testWidgets("doesn't invoke anything without user interaction", - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets("doesn't invoke anything without user interaction", (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: CustomScrollView( diff --git a/packages/flutter/test/painting/decoration_image_lerp_test.dart b/packages/flutter/test/painting/decoration_image_lerp_test.dart index fbdc03918f5..8586abbd9ad 100644 --- a/packages/flutter/test/painting/decoration_image_lerp_test.dart +++ b/packages/flutter/test/painting/decoration_image_lerp_test.dart @@ -18,7 +18,7 @@ import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { testWidgets('ImageDecoration.lerp', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] + // TODO(polina-c): make sure images are disposed, https://github.com/flutter/flutter/issues/141388 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final MemoryImage green = MemoryImage(Uint8List.fromList([ @@ -195,7 +195,7 @@ void main() { }, skip: kIsWeb); // TODO(ianh): https://github.com/flutter/flutter/issues/130612, https://github.com/flutter/flutter/issues/130609 testWidgets('ImageDecoration.lerp', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] + // TODO(polina-c): make sure images are disposed, https://github.com/flutter/flutter/issues/141388 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final MemoryImage cmyk = MemoryImage(Uint8List.fromList([ @@ -416,7 +416,7 @@ void main() { }, skip: kIsWeb); // TODO(ianh): https://github.com/flutter/flutter/issues/130612, https://github.com/flutter/flutter/issues/130609 testWidgets('ImageDecoration.lerp with colored background', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] + // TODO(polina-c): make sure images are disposed, https://github.com/flutter/flutter/issues/141388 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final MemoryImage cmyk = MemoryImage(Uint8List.fromList([ diff --git a/packages/flutter/test/painting/image_stream_test.dart b/packages/flutter/test/painting/image_stream_test.dart index e29cd450527..ab1f51c7215 100644 --- a/packages/flutter/test/painting/image_stream_test.dart +++ b/packages/flutter/test/painting/image_stream_test.dart @@ -78,7 +78,7 @@ class FakeEventReportingImageStreamCompleter extends ImageStreamCompleter { } void main() { - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] + // TODO(polina-c): make sure images are disposed, https://github.com/flutter/flutter/issues/141388 [leaks-to-clean] LeakTesting.settings = LeakTesting.settings.withIgnoredAll(); late Image image20x10; diff --git a/packages/flutter/test/semantics/semantics_elevation_test.dart b/packages/flutter/test/semantics/semantics_elevation_test.dart index b9d37d0bc60..24c6918af2b 100644 --- a/packages/flutter/test/semantics/semantics_elevation_test.dart +++ b/packages/flutter/test/semantics/semantics_elevation_test.dart @@ -5,15 +5,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../widgets/semantics_tester.dart'; void main() { - testWidgets('SemanticsNodes overlapping in z', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('SemanticsNodes overlapping in z', (WidgetTester tester) async { // Cards are semantic boundaries that always own their own SemanticNode, // PhysicalModels merge their semantics information into parent. // diff --git a/packages/flutter/test/widgets/basic_test.dart b/packages/flutter/test/widgets/basic_test.dart index 73eb1c16447..567f2e37bf3 100644 --- a/packages/flutter/test/widgets/basic_test.dart +++ b/packages/flutter/test/widgets/basic_test.dart @@ -15,16 +15,12 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { group('RawImage', () { - testWidgets('properties', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('properties', (WidgetTester tester) async { final ui.Image image1 = (await tester.runAsync(() => createTestImage()))!; await tester.pumpWidget(