diff --git a/packages/flutter/lib/src/material/tooltip.dart b/packages/flutter/lib/src/material/tooltip.dart index 26ac1b266d..698619ee9c 100644 --- a/packages/flutter/lib/src/material/tooltip.dart +++ b/packages/flutter/lib/src/material/tooltip.dart @@ -529,7 +529,7 @@ class TooltipState extends State with SingleTickerProviderStateMixin { /// Returns `false` when the tooltip shouldn't be shown or when the tooltip /// was already visible. bool ensureTooltipVisible() { - if (!_visible) { + if (!_visible || !mounted) { return false; } _showTimer?.cancel(); diff --git a/packages/flutter/test/material/tooltip_test.dart b/packages/flutter/test/material/tooltip_test.dart index 01fcd2547f..da4f23e72a 100644 --- a/packages/flutter/test/material/tooltip_test.dart +++ b/packages/flutter/test/material/tooltip_test.dart @@ -1053,6 +1053,37 @@ void main() { gesture = null; }); + testWidgets('Calling ensureTooltipVisible on an unmounted TooltipState returns false', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/95851 + await tester.pumpWidget( + const MaterialApp( + home: Center( + child: Tooltip( + message: tooltipText, + child: SizedBox( + width: 100.0, + height: 100.0, + ), + ), + ), + ), + ); + + final TooltipState tooltipState = tester.state(find.byType(Tooltip)); + expect(tooltipState.ensureTooltipVisible(), true); + + // Remove the tooltip. + await tester.pumpWidget( + const MaterialApp( + home: Center( + child: SizedBox.shrink(), + ), + ), + ); + + expect(tooltipState.ensureTooltipVisible(), false); + }); + testWidgets('Tooltip shows/hides when hovered', (WidgetTester tester) async { const Duration waitDuration = Duration.zero; TestGesture? gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);