diff --git a/packages/flutter/lib/src/cupertino/app.dart b/packages/flutter/lib/src/cupertino/app.dart index 43f92f5694..b4b0b818fa 100644 --- a/packages/flutter/lib/src/cupertino/app.dart +++ b/packages/flutter/lib/src/cupertino/app.dart @@ -506,6 +506,12 @@ class _CupertinoAppState extends State { _heroController = CupertinoApp.createCupertinoHeroController(); } + @override + void dispose() { + _heroController.dispose(); + super.dispose(); + } + // Combine the default localization for Cupertino with the ones contributed // by the localizationsDelegates parameter, if any. Only the first delegate // of a particular LocalizationsDelegate.type is loaded so the diff --git a/packages/flutter/lib/src/cupertino/route.dart b/packages/flutter/lib/src/cupertino/route.dart index c53efc7e87..a354078c02 100644 --- a/packages/flutter/lib/src/cupertino/route.dart +++ b/packages/flutter/lib/src/cupertino/route.dart @@ -121,6 +121,12 @@ mixin CupertinoRouteTransitionMixin on PageRoute { return _previousTitle!; } + @override + void dispose() { + _previousTitle?.dispose(); + super.dispose(); + } + @override void didChangePrevious(Route? previousRoute) { final String? previousTitleString = previousRoute is CupertinoRouteTransitionMixin diff --git a/packages/flutter/test/cupertino/app_test.dart b/packages/flutter/test/cupertino/app_test.dart index d61df5b38c..50265a8f66 100644 --- a/packages/flutter/test/cupertino/app_test.dart +++ b/packages/flutter/test/cupertino/app_test.dart @@ -7,9 +7,10 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.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() { - testWidgets('Heroes work', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Heroes work', (WidgetTester tester) async { await tester.pumpWidget(CupertinoApp( home: ListView(children: [ const Hero(tag: 'a', child: Text('foo')), @@ -394,6 +395,11 @@ void main() { return renderEditable!; } + final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); + final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); + await tester.pumpWidget( CupertinoApp( theme: const CupertinoThemeData( @@ -405,8 +411,8 @@ void main() { return EditableText( backgroundCursorColor: DefaultSelectionStyle.of(context).selectionColor!, cursorColor: DefaultSelectionStyle.of(context).cursorColor!, - controller: TextEditingController(), - focusNode: FocusNode(), + controller: controller, + focusNode: focusNode, style: const TextStyle(), ); },