Unverified Commit c4b11d80 authored by hangyu's avatar hangyu Committed by GitHub

Make it possible to disable tapping to dismiss a tooltip. (#137375)

issue: https://github.com/flutter/flutter/issues/137438

Use case: I want to add action button is tooltip and thus want to disable tap to dismiss a tooltip.

![image](https://github.com/flutter/flutter/assets/108393416/39c606fd-d301-4ed4-a411-4916823e5757)
parent e65c2681
...@@ -185,6 +185,7 @@ class Tooltip extends StatefulWidget { ...@@ -185,6 +185,7 @@ class Tooltip extends StatefulWidget {
this.textAlign, this.textAlign,
this.waitDuration, this.waitDuration,
this.showDuration, this.showDuration,
this.enableTapToDismiss = true,
this.triggerMode, this.triggerMode,
this.enableFeedback, this.enableFeedback,
this.onTriggered, this.onTriggered,
...@@ -307,6 +308,11 @@ class Tooltip extends StatefulWidget { ...@@ -307,6 +308,11 @@ class Tooltip extends StatefulWidget {
/// for mouse pointer exits the widget. /// for mouse pointer exits the widget.
final Duration? showDuration; final Duration? showDuration;
/// Whether the tooltip can be dismissed by tap.
///
/// The default value is true.
final bool enableTapToDismiss;
/// The [TooltipTriggerMode] that will show the tooltip. /// The [TooltipTriggerMode] that will show the tooltip.
/// ///
/// If this property is null, then [TooltipThemeData.triggerMode] is used. /// If this property is null, then [TooltipThemeData.triggerMode] is used.
...@@ -581,6 +587,9 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin { ...@@ -581,6 +587,9 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
// The primary pointer is not part of a "trigger" gesture so the tooltip // The primary pointer is not part of a "trigger" gesture so the tooltip
// should be dismissed. // should be dismissed.
void _handleTapToDismiss() { void _handleTapToDismiss() {
if (!widget.enableTapToDismiss) {
return ;
}
_scheduleDismissTooltip(withDelay: Duration.zero); _scheduleDismissTooltip(withDelay: Duration.zero);
_activeHoveringPointerDevices.clear(); _activeHoveringPointerDevices.clear();
} }
......
...@@ -1016,6 +1016,39 @@ void main() { ...@@ -1016,6 +1016,39 @@ void main() {
expect(find.text(tooltipText), findsNothing); expect(find.text(tooltipText), findsNothing);
}); });
testWidgetsWithLeakTracking('Tooltip is dismissed after tap to dismiss immediately', (WidgetTester tester) async {
await setWidgetForTooltipMode(tester, TooltipTriggerMode.tap);
final Finder tooltip = find.byType(Tooltip);
expect(find.text(tooltipText), findsNothing);
// Tap to trigger the tooltip.
await _testGestureTap(tester, tooltip);
expect(find.text(tooltipText), findsOneWidget);
// Tap to dismiss the tooltip. Tooltip is dismissed immediately.
await _testGestureTap(tester, find.text(tooltipText));
await tester.pump(const Duration(milliseconds: 10));
expect(find.text(tooltipText), findsNothing);
});
testWidgetsWithLeakTracking('Tooltip is not dismissed after tap if enableTapToDismiss is false', (WidgetTester tester) async {
await setWidgetForTooltipMode(tester, TooltipTriggerMode.tap, enableTapToDismiss: false);
final Finder tooltip = find.byType(Tooltip);
expect(find.text(tooltipText), findsNothing);
// Tap to trigger the tooltip.
await _testGestureTap(tester, tooltip);
expect(find.text(tooltipText), findsOneWidget);
// Tap the tooltip. Tooltip is not dismissed .
await _testGestureTap(tester, find.text(tooltipText));
await tester.pump(const Duration(milliseconds: 10));
expect(find.text(tooltipText), findsOneWidget);
});
testWidgetsWithLeakTracking('Tooltip is dismissed after a tap and showDuration expired when competing with a GestureDetector', (WidgetTester tester) async { testWidgetsWithLeakTracking('Tooltip is dismissed after a tap and showDuration expired when competing with a GestureDetector', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/98854 // Regression test for https://github.com/flutter/flutter/issues/98854
const Duration showDuration = Duration(seconds: 3); const Duration showDuration = Duration(seconds: 3);
...@@ -2480,6 +2513,7 @@ Future<void> setWidgetForTooltipMode( ...@@ -2480,6 +2513,7 @@ Future<void> setWidgetForTooltipMode(
WidgetTester tester, WidgetTester tester,
TooltipTriggerMode triggerMode, { TooltipTriggerMode triggerMode, {
Duration? showDuration, Duration? showDuration,
bool? enableTapToDismiss,
TooltipTriggeredCallback? onTriggered, TooltipTriggeredCallback? onTriggered,
}) async { }) async {
await tester.pumpWidget( await tester.pumpWidget(
...@@ -2489,6 +2523,7 @@ Future<void> setWidgetForTooltipMode( ...@@ -2489,6 +2523,7 @@ Future<void> setWidgetForTooltipMode(
triggerMode: triggerMode, triggerMode: triggerMode,
onTriggered: onTriggered, onTriggered: onTriggered,
showDuration: showDuration, showDuration: showDuration,
enableTapToDismiss: enableTapToDismiss ?? true,
child: const SizedBox(width: 100.0, height: 100.0), child: const SizedBox(width: 100.0, height: 100.0),
), ),
), ),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment