diff --git a/packages/flutter/lib/src/material/icon_button.dart b/packages/flutter/lib/src/material/icon_button.dart index ade4e84e6677a..88a9a36e24032 100644 --- a/packages/flutter/lib/src/material/icon_button.dart +++ b/packages/flutter/lib/src/material/icon_button.dart @@ -880,6 +880,12 @@ class _SelectableIconButtonState extends State<_SelectableIconButton> { ), ); } + + @override + void dispose() { + statesController.dispose(); + super.dispose(); + } } class _IconButtonM3 extends ButtonStyleButton { diff --git a/packages/flutter/test/material/icon_button_test.dart b/packages/flutter/test/material/icon_button_test.dart index 2bbe170f2a296..bd8b6c3b5b0e7 100644 --- a/packages/flutter/test/material/icon_button_test.dart +++ b/packages/flutter/test/material/icon_button_test.dart @@ -8,6 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import '../foundation/leak_tracking.dart'; import '../rendering/mock_canvas.dart'; import '../widgets/semantics_tester.dart'; import 'feedback_tester.dart'; @@ -2729,18 +2730,18 @@ void main() { final ColorScheme lightScheme = const ColorScheme.light().copyWith(onSurfaceVariant: const Color(0xffe91e60)); // Brightness.dark await tester.pumpWidget( - MaterialApp( - theme: ThemeData(colorScheme: lightScheme, useMaterial3: true,), - home: Scaffold( - body: IconTheme.merge( - data: const IconThemeData(size: 26), - child: IconButton( - icon: const Icon(Icons.account_box), - onPressed: () {}, - ), - ), - ) + MaterialApp( + theme: ThemeData(colorScheme: lightScheme, useMaterial3: true,), + home: Scaffold( + body: IconTheme.merge( + data: const IconThemeData(size: 26), + child: IconButton( + icon: const Icon(Icons.account_box), + onPressed: () {}, + ), + ), ) + ) ); Color? iconColor0() => _iconStyle(tester, Icons.account_box)?.color; @@ -2770,6 +2771,25 @@ void main() { expect(tester.takeException(), isNull); }); + + testWidgetsWithLeakTracking('Material3 - IconButton memory leak', (WidgetTester tester) async { + // This is a regression test for https://github.com/flutter/flutter/issues/130708. + Widget buildWidget(bool showIconButton) { + return showIconButton + ? MaterialApp( + theme: ThemeData(useMaterial3: true), + home: IconButton( + onPressed: () { }, + icon: const Icon(Icons.search), + ), + ) + : const SizedBox(); + } + await tester.pumpWidget(buildWidget(true)); + await tester.pumpWidget(buildWidget(false)); + + // No exception is thrown. + }); }); }