Improvements to EditableText documentation (#132532)
diff --git a/packages/flutter/lib/src/rendering/editable.dart b/packages/flutter/lib/src/rendering/editable.dart
index 779e383..2dd8671 100644
--- a/packages/flutter/lib/src/rendering/editable.dart
+++ b/packages/flutter/lib/src/rendering/editable.dart
@@ -878,7 +878,9 @@
/// The color to use when painting the cursor aligned to the text while
/// rendering the floating cursor.
///
- /// The default is light grey.
+ /// Typically this would be set to [CupertinoColors.inactiveGray].
+ ///
+ /// If this is null, the background cursor is not painted.
Color? get backgroundCursorColor => _caretPainter.backgroundCursorColor;
set backgroundCursorColor(Color? value) {
_caretPainter.backgroundCursorColor = value;
@@ -2645,8 +2647,8 @@
/// when only auxiliary content changes (e.g. a blinking cursor) are present. It
/// will be scheduled to repaint when:
///
-/// * It's assigned to a new [RenderEditable] and the [shouldRepaint] method
-/// returns true.
+/// * It's assigned to a new [RenderEditable] (replacing a prior
+/// [RenderEditablePainter]) and the [shouldRepaint] method returns true.
/// * Any of the [RenderEditable]s it is attached to repaints.
/// * The [notifyListeners] method is called, which typically happens when the
/// painter's attributes change.
@@ -2657,9 +2659,8 @@
/// and sets it as the foreground painter of the [RenderEditable].
/// * [RenderEditable.painter], which takes a [RenderEditablePainter]
/// and sets it as the background painter of the [RenderEditable].
-/// * [CustomPainter] a similar class which paints within a [RenderCustomPaint].
+/// * [CustomPainter], a similar class which paints within a [RenderCustomPaint].
abstract class RenderEditablePainter extends ChangeNotifier {
-
/// Determines whether repaint is needed when a new [RenderEditablePainter]
/// is provided to a [RenderEditable].
///
@@ -2795,6 +2796,11 @@
notifyListeners();
}
+ // This is directly manipulated by the RenderEditable during
+ // setFloatingCursor.
+ //
+ // When changing this value, the caller is responsible for ensuring that
+ // listeners are notified.
bool showRegularCaret = false;
final Paint caretPaint = Paint();
diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart
index b8effd5..da20140 100644
--- a/packages/flutter/lib/src/widgets/editable_text.dart
+++ b/packages/flutter/lib/src/widgets/editable_text.dart
@@ -206,7 +206,7 @@
value == null || !value.composing.isValid || value.isComposingRangeValid,
'New TextEditingValue $value has an invalid non-empty composing range '
'${value.composing}. It is recommended to use a valid composing range, '
- 'even for readonly text fields',
+ 'even for readonly text fields.',
),
super(value ?? TextEditingValue.empty);
@@ -235,7 +235,7 @@
!newValue.composing.isValid || newValue.isComposingRangeValid,
'New TextEditingValue $newValue has an invalid non-empty composing range '
'${newValue.composing}. It is recommended to use a valid composing range, '
- 'even for readonly text fields',
+ 'even for readonly text fields.',
);
super.value = newValue;
}
@@ -547,8 +547,11 @@
///
/// This widget interacts with the [TextInput] service to let the user edit the
/// text it contains. It also provides scrolling, selection, and cursor
-/// movement. This widget does not provide any focus management (e.g.,
-/// tap-to-focus).
+/// movement.
+///
+/// The [EditableText] widget is a low-level widget that is intended as a
+/// building block for custom widget sets. For a complete user experience,
+/// consider using a [TextField] or [CupertinoTextField].
///
/// ## Handling User Input
///
@@ -662,13 +665,14 @@
///
/// ## Gesture Events Handling
///
-/// This widget provides rudimentary, platform-agnostic gesture handling for
-/// user actions such as tapping, long-pressing and scrolling when
-/// [rendererIgnoresPointer] is false (false by default). To tightly conform
-/// to the platform behavior with respect to input gestures in text fields, use
-/// [TextField] or [CupertinoTextField]. For custom selection behavior, call
-/// methods such as [RenderEditable.selectPosition],
-/// [RenderEditable.selectWord], etc. programmatically.
+/// When [rendererIgnoresPointer] is false (the default), this widget provides
+/// rudimentary, platform-agnostic gesture handling for user actions such as
+/// tapping, long-pressing, and scrolling.
+///
+/// To provide more complete gesture handling, including double-click to select
+/// a word, drag selection, and platform-specific handling of gestures such as
+/// long presses, consider setting [rendererIgnoresPointer] to true and using
+/// [TextSelectionGestureDetectorBuilder].
///
/// {@template flutter.widgets.editableText.showCaretOnScreen}
/// ## Keep the caret visible when focused
@@ -696,7 +700,7 @@
/// a currency value text field. The following example demonstrates how to
/// suppress the default accessibility announcements by always announcing
/// the content of the text field as a US currency value (the `\$` inserts
-/// a dollar sign, the `$newText interpolates the `newText` variable):
+/// a dollar sign, the `$newText` interpolates the `newText` variable):
///
/// ```dart
/// onChanged: (String newText) {
@@ -726,14 +730,6 @@
///
/// The text cursor is not shown if [showCursor] is false or if [showCursor]
/// is null (the default) and [readOnly] is true.
- ///
- /// The [controller], [focusNode], [obscureText], [autocorrect], [autofocus],
- /// [showSelectionHandles], [enableInteractiveSelection], [forceLine],
- /// [style], [cursorColor], [cursorOpacityAnimates], [backgroundCursorColor],
- /// [enableSuggestions], [paintCursorAboveText], [selectionHeightStyle],
- /// [selectionWidthStyle], [textAlign], [dragStartBehavior], [scrollPadding],
- /// [dragStartBehavior], [toolbarOptions], [rendererIgnoresPointer],
- /// [readOnly], and [enableIMEPersonalizedLearning] arguments must not be null.
EditableText({
super.key,
required this.controller,
@@ -1101,8 +1097,7 @@
/// The color to use when painting the background cursor aligned with the text
/// while rendering the floating cursor.
///
- /// Cannot be null. By default it is the disabled grey color from
- /// CupertinoColors.
+ /// Typically this would be set to [CupertinoColors.inactiveGray].
final Color backgroundCursorColor;
/// {@template flutter.widgets.editableText.maxLines}
@@ -1473,10 +1468,28 @@
/// the editing position.
final MouseCursor? mouseCursor;
- /// If true, the [RenderEditable] created by this widget will not handle
- /// pointer events, see [RenderEditable] and [RenderEditable.ignorePointer].
+ /// Whether the caller will provide gesture handling (true), or if the
+ /// [EditableText] is expected to handle basic gestures (false).
+ ///
+ /// When this is false, the [EditableText] (or more specifically, the
+ /// [RenderEditable]) enables some rudimentary gestures (tap to position the
+ /// cursor, long-press to select all, and some scrolling behavior).
+ ///
+ /// These behaviors are sufficient for debugging purposes but are inadequate
+ /// for user-facing applications. To enable platform-specific behaviors, use a
+ /// [TextSelectionGestureDetectorBuilder] to wrap the [EditableText], and set
+ /// [rendererIgnoresPointer] to true.
+ ///
+ /// When [rendererIgnoresPointer] is true true, the [RenderEditable] created
+ /// by this widget will not handle pointer events.
///
/// This property is false by default.
+ ///
+ /// See also:
+ ///
+ /// * [RenderEditable.ignorePointer], which implements this feature.
+ /// * [TextSelectionGestureDetectorBuilder], which implements platform-specific
+ /// gestures and behaviors.
final bool rendererIgnoresPointer;
/// {@template flutter.widgets.editableText.cursorWidth}
diff --git a/packages/flutter/lib/src/widgets/text_selection.dart b/packages/flutter/lib/src/widgets/text_selection.dart
index 274150a..12d780c 100644
--- a/packages/flutter/lib/src/widgets/text_selection.dart
+++ b/packages/flutter/lib/src/widgets/text_selection.dart
@@ -1871,12 +1871,13 @@
/// Delegate interface for the [TextSelectionGestureDetectorBuilder].
///
-/// The interface is usually implemented by text field implementations wrapping
-/// [EditableText], that use a [TextSelectionGestureDetectorBuilder] to build a
-/// [TextSelectionGestureDetector] for their [EditableText]. The delegate provides
-/// the builder with information about the current state of the text field.
-/// Based on these information, the builder adds the correct gesture handlers
-/// to the gesture detector.
+/// The interface is usually implemented by the [State] of text field
+/// implementations wrapping [EditableText], so that they can use a
+/// [TextSelectionGestureDetectorBuilder] to build a
+/// [TextSelectionGestureDetector] for their [EditableText]. The delegate
+/// provides the builder with information about the current state of the text
+/// field. Based on that information, the builder adds the correct gesture
+/// handlers to the gesture detector.
///
/// See also:
///
@@ -1907,6 +1908,12 @@
/// The resulting [TextSelectionGestureDetector] to wrap an [EditableText] is
/// obtained by calling [buildGestureDetector].
///
+/// A [TextSelectionGestureDetectorBuilder] must be provided a
+/// [TextSelectionGestureDetectorBuilderDelegate], from which information about
+/// the [EditableText] may be obtained. Typically, the [State] of the widget
+/// that builds the [EditableText] implements this interface, and then passes
+/// itself as the [delegate].
+///
/// See also:
///
/// * [TextField], which uses a subclass to implement the Material-specific
@@ -1915,8 +1922,6 @@
/// Cupertino-specific gesture logic of an [EditableText].
class TextSelectionGestureDetectorBuilder {
/// Creates a [TextSelectionGestureDetectorBuilder].
- ///
- /// The [delegate] must not be null.
TextSelectionGestureDetectorBuilder({
required this.delegate,
});
@@ -1926,6 +1931,9 @@
/// The delegate provides the builder with information about what actions can
/// currently be performed on the text field. Based on this, the builder adds
/// the correct gesture handlers to the gesture detector.
+ ///
+ /// Typically implemented by a [State] of a widget that builds an
+ /// [EditableText].
@protected
final TextSelectionGestureDetectorBuilderDelegate delegate;
@@ -2971,7 +2979,9 @@
/// Returns a [TextSelectionGestureDetector] configured with the handlers
/// provided by this builder.
///
- /// The [child] or its subtree should contain [EditableText].
+ /// The [child] or its subtree should contain an [EditableText] whose key is
+ /// the [GlobalKey] provided by the [delegate]'s
+ /// [TextSelectionGestureDetectorBuilderDelegate.editableTextKey].
Widget buildGestureDetector({
Key? key,
HitTestBehavior? behavior,