Add CupertinoTextField.onTap (#34964)
diff --git a/packages/flutter/lib/src/cupertino/text_field.dart b/packages/flutter/lib/src/cupertino/text_field.dart
index 09a0e0c..5cc8b26 100644
--- a/packages/flutter/lib/src/cupertino/text_field.dart
+++ b/packages/flutter/lib/src/cupertino/text_field.dart
@@ -196,6 +196,7 @@
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.start,
this.enableInteractiveSelection,
+ this.onTap,
this.scrollController,
this.scrollPhysics,
}) : assert(textAlign != null),
@@ -458,6 +459,9 @@
return enableInteractiveSelection ?? !obscureText;
}
+ /// {@macro flutter.material.textfield.onTap}
+ final GestureTapCallback onTap;
+
@override
_CupertinoTextFieldState createState() => _CupertinoTextFieldState();
@@ -584,6 +588,9 @@
_renderEditable.selectWordEdge(cause: SelectionChangedCause.tap);
}
_requestKeyboard();
+ if (widget.onTap != null) {
+ widget.onTap();
+ }
}
void _handleSingleLongTapStart(LongPressStartDetails details) {
diff --git a/packages/flutter/lib/src/material/text_field.dart b/packages/flutter/lib/src/material/text_field.dart
index e8061e2..cce50a1 100644
--- a/packages/flutter/lib/src/material/text_field.dart
+++ b/packages/flutter/lib/src/material/text_field.dart
@@ -432,7 +432,8 @@
return enableInteractiveSelection ?? !obscureText;
}
- /// Called when the user taps on this text field.
+ /// {@template flutter.material.textfield.onTap}
+ /// Called for each distinct tap except for every second tap of a double tap.
///
/// The text field builds a [GestureDetector] to handle input events like tap,
/// to trigger focus requests, to move the caret, adjust the selection, etc.
@@ -450,6 +451,7 @@
///
/// To listen to arbitrary pointer events without competing with the
/// text field's internal gesture detector, use a [Listener].
+ /// {@endtemplate}
final GestureTapCallback onTap;
/// Callback that generates a custom [InputDecorator.counter] widget.
diff --git a/packages/flutter/test/cupertino/text_field_test.dart b/packages/flutter/test/cupertino/text_field_test.dart
index 3ac4098..7183fdb 100644
--- a/packages/flutter/test/cupertino/text_field_test.dart
+++ b/packages/flutter/test/cupertino/text_field_test.dart
@@ -2512,6 +2512,90 @@
},
);
+ testWidgets('onTap is called upon tap', (WidgetTester tester) async {
+ int tapCount = 0;
+ await tester.pumpWidget(
+ CupertinoApp(
+ home: Center(
+ child: CupertinoTextField(
+ onTap: () => tapCount++,
+ ),
+ ),
+ ),
+ );
+
+ expect(tapCount, 0);
+ await tester.tap(find.byType(CupertinoTextField));
+ await tester.pump();
+ expect(tapCount, 1);
+
+ // Wait out the double tap interval so the next tap doesn't end up being
+ // recognized as a double tap.
+ await tester.pump(const Duration(seconds: 1));
+
+ // Double tap count as one single tap.
+ await tester.tap(find.byType(CupertinoTextField));
+ await tester.pump(const Duration(milliseconds: 100));
+ await tester.tap(find.byType(CupertinoTextField));
+ await tester.pump();
+ expect(tapCount, 2);
+ });
+
+ testWidgets('onTap does not work when the text field is disabled',
+ (WidgetTester tester) async {
+ int tapCount = 0;
+ await tester.pumpWidget(
+ CupertinoApp(
+ home: Center(
+ child: CupertinoTextField(
+ enabled: false,
+ onTap: () => tapCount++,
+ ),
+ ),
+ ),
+ );
+
+ expect(tapCount, 0);
+ await tester.tap(find.byType(CupertinoTextField));
+ await tester.pump();
+ expect(tapCount, 0);
+
+ // Wait out the double tap interval so the next tap doesn't end up being
+ // recognized as a double tap.
+ await tester.pump(const Duration(seconds: 1));
+
+ // Enabling the text field, now it should accept taps.
+ await tester.pumpWidget(
+ CupertinoApp(
+ home: Center(
+ child: CupertinoTextField(
+ onTap: () => tapCount++,
+ ),
+ ),
+ ),
+ );
+
+ await tester.tap(find.byType(CupertinoTextField));
+ expect(tapCount, 1);
+
+ await tester.pump(const Duration(seconds: 1));
+
+ // Disable it again.
+ await tester.pumpWidget(
+ CupertinoApp(
+ home: Center(
+ child: CupertinoTextField(
+ enabled: false,
+ onTap: () => tapCount++,
+ ),
+ ),
+ ),
+ );
+ await tester.tap(find.byType(CupertinoTextField));
+ await tester.pump();
+ expect(tapCount, 1);
+ });
+
testWidgets(
'text field respects theme',
(WidgetTester tester) async {