Unverified Commit b63ced55 authored by xster's avatar xster Committed by GitHub

Add a CupertinoTextField (#23194)

parent dc36195c
...@@ -11,3 +11,4 @@ export 'cupertino_refresh_demo.dart'; ...@@ -11,3 +11,4 @@ export 'cupertino_refresh_demo.dart';
export 'cupertino_segmented_control_demo.dart'; export 'cupertino_segmented_control_demo.dart';
export 'cupertino_slider_demo.dart'; export 'cupertino_slider_demo.dart';
export 'cupertino_switch_demo.dart'; export 'cupertino_switch_demo.dart';
export 'cupertino_text_field_demo.dart';
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
class CupertinoTextFieldDemo extends StatefulWidget {
static const String routeName = '/cupertino/text_fields';
@override
_CupertinoTextFieldDemoState createState() {
return _CupertinoTextFieldDemoState();
}
}
class _CupertinoTextFieldDemoState extends State<CupertinoTextFieldDemo> {
TextEditingController _chatTextController;
TextEditingController _locationTextController;
@override
void initState() {
super.initState();
_chatTextController = TextEditingController();
_locationTextController = TextEditingController(text: 'Montreal, Canada');
}
Widget _buildChatTextField() {
return CupertinoTextField(
controller: _chatTextController,
textCapitalization: TextCapitalization.sentences,
placeholder: 'Text Message',
decoration: BoxDecoration(
border: Border.all(
width: 0.0,
color: CupertinoColors.inactiveGray,
),
borderRadius: BorderRadius.circular(15.0),
),
maxLines: null,
keyboardType: TextInputType.multiline,
prefix: const Padding(padding: EdgeInsets.symmetric(horizontal: 4.0)),
suffix: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: CupertinoButton(
color: CupertinoColors.activeGreen,
minSize: 0.0,
child: const Icon(
CupertinoIcons.up_arrow,
size: 21.0,
color: CupertinoColors.white,
),
padding: const EdgeInsets.all(2.0),
borderRadius: BorderRadius.circular(15.0),
onPressed: ()=> setState(()=> _chatTextController.clear()),
),
),
autofocus: true,
suffixMode: OverlayVisibilityMode.editing,
onSubmitted: (String text)=> setState(()=> _chatTextController.clear()),
);
}
Widget _buildNameField() {
return const CupertinoTextField(
prefix: Icon(
CupertinoIcons.person_solid,
color: CupertinoColors.lightBackgroundGray,
size: 28.0,
),
padding: EdgeInsets.symmetric(horizontal: 6.0, vertical: 12.0),
clearButtonMode: OverlayVisibilityMode.editing,
textCapitalization: TextCapitalization.words,
autocorrect: false,
decoration: BoxDecoration(
border: Border(bottom: BorderSide(width: 0.0, color: CupertinoColors.inactiveGray)),
),
placeholder: 'Name',
);
}
Widget _buildEmailField() {
return const CupertinoTextField(
prefix: Icon(
CupertinoIcons.mail_solid,
color: CupertinoColors.lightBackgroundGray,
size: 28.0,
),
padding: EdgeInsets.symmetric(horizontal: 6.0, vertical: 12.0),
clearButtonMode: OverlayVisibilityMode.editing,
keyboardType: TextInputType.emailAddress,
autocorrect: false,
decoration: BoxDecoration(
border: Border(bottom: BorderSide(width: 0.0, color: CupertinoColors.inactiveGray)),
),
placeholder: 'Email',
);
}
Widget _buildLocationField() {
return CupertinoTextField(
controller: _locationTextController,
prefix: const Icon(
CupertinoIcons.location_solid,
color: CupertinoColors.lightBackgroundGray,
size: 28.0,
),
padding: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 12.0),
clearButtonMode: OverlayVisibilityMode.editing,
textCapitalization: TextCapitalization.words,
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(width: 0.0, color: CupertinoColors.inactiveGray)),
),
placeholder: 'Location',
);
}
Widget _buildPinField() {
return const CupertinoTextField(
prefix: Icon(
CupertinoIcons.padlock_solid,
color: CupertinoColors.lightBackgroundGray,
size: 28.0,
),
padding: EdgeInsets.symmetric(horizontal: 6.0, vertical: 12.0),
clearButtonMode: OverlayVisibilityMode.editing,
keyboardType: TextInputType.number,
autocorrect: false,
obscureText: true,
decoration: BoxDecoration(
border: Border(bottom: BorderSide(width: 0.0, color: CupertinoColors.inactiveGray)),
),
placeholder: 'Create a PIN',
);
}
Widget _buildTagsField() {
return CupertinoTextField(
controller: TextEditingController(text: 'colleague, reading club'),
prefix: const Icon(
CupertinoIcons.tags_solid,
color: CupertinoColors.lightBackgroundGray,
size: 28.0,
),
enabled: false,
padding: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 12.0),
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(width: 0.0, color: CupertinoColors.inactiveGray)),
),
);
}
@override
Widget build(BuildContext context) {
return DefaultTextStyle(
style: const TextStyle(
fontFamily: '.SF UI Text',
inherit: false,
fontSize: 17.0,
color: CupertinoColors.black,
),
child: CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
previousPageTitle: 'Cupertino',
middle: Text('Text Fields'),
),
child: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 32.0, horizontal: 16.0),
child: Column(
children: <Widget>[
_buildNameField(),
_buildEmailField(),
_buildLocationField(),
_buildPinField(),
_buildTagsField(),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 32.0, horizontal: 16.0),
child: _buildChatTextField(),
),
],
),
),
);
}
}
...@@ -500,6 +500,13 @@ List<GalleryDemo> _buildGalleryDemos() { ...@@ -500,6 +500,13 @@ List<GalleryDemo> _buildGalleryDemos() {
documentationUrl: 'https://docs.flutter.io/flutter/cupertino/CupertinoSwitch-class.html', documentationUrl: 'https://docs.flutter.io/flutter/cupertino/CupertinoSwitch-class.html',
buildRoute: (BuildContext context) => CupertinoSwitchDemo(), buildRoute: (BuildContext context) => CupertinoSwitchDemo(),
), ),
GalleryDemo(
title: 'Text Fields',
icon: GalleryIcons.text_fields_alt,
category: _kCupertinoComponents,
routeName: CupertinoTextFieldDemo.routeName,
buildRoute: (BuildContext context) => CupertinoTextFieldDemo(),
),
// Media // Media
GalleryDemo( GalleryDemo(
......
...@@ -28,6 +28,7 @@ export 'src/cupertino/slider.dart'; ...@@ -28,6 +28,7 @@ export 'src/cupertino/slider.dart';
export 'src/cupertino/switch.dart'; export 'src/cupertino/switch.dart';
export 'src/cupertino/tab_scaffold.dart'; export 'src/cupertino/tab_scaffold.dart';
export 'src/cupertino/tab_view.dart'; export 'src/cupertino/tab_view.dart';
export 'src/cupertino/text_field.dart';
export 'src/cupertino/text_selection.dart'; export 'src/cupertino/text_selection.dart';
export 'src/cupertino/thumb_painter.dart'; export 'src/cupertino/thumb_painter.dart';
export 'widgets.dart'; export 'widgets.dart';
...@@ -243,7 +243,7 @@ class _CupertinoAppState extends State<CupertinoApp> { ...@@ -243,7 +243,7 @@ class _CupertinoAppState extends State<CupertinoApp> {
_navigatorObservers = List<NavigatorObserver>.from(widget.navigatorObservers) _navigatorObservers = List<NavigatorObserver>.from(widget.navigatorObservers)
..add(_heroController); ..add(_heroController);
} else { } else {
_navigatorObservers = null; _navigatorObservers = const <NavigatorObserver>[];
} }
} }
......
...@@ -721,4 +721,44 @@ class CupertinoIcons { ...@@ -721,4 +721,44 @@ class CupertinoIcons {
/// * [group], which is similar, but not filled in. /// * [group], which is similar, but not filled in.
/// * [person_solid], which is just a single person. /// * [person_solid], which is just a single person.
static const IconData group_solid = IconData(0xf47c, fontFamily: iconFont, fontPackage: iconFontPackage); static const IconData group_solid = IconData(0xf47c, fontFamily: iconFont, fontPackage: iconFontPackage);
/// Outline of a closed mail envelope.
static const IconData mail = IconData(0xf422, fontFamily: iconFont, fontPackage: iconFontPackage);
/// A closed mail envelope. This icon is filled in.
static const IconData mail_solid = IconData(0xf423, fontFamily: iconFont, fontPackage: iconFontPackage);
/// Outline of a location pin.
static const IconData location = IconData(0xf455, fontFamily: iconFont, fontPackage: iconFontPackage);
/// A location pin. This icon is filled in.
static const IconData location_solid = IconData(0xf456, fontFamily: iconFont, fontPackage: iconFontPackage);
/// Outline of a sticker tag.
///
/// See also:
///
/// * [tags], similar but with 2 overlapping tags.
static const IconData tag = IconData(0xf48c, fontFamily: iconFont, fontPackage: iconFontPackage);
/// A sticker tag. This icon is filled in.
///
/// See also:
///
/// * [tags_solid], similar but with 2 overlapping tags.
static const IconData tag_solid = IconData(0xf48d, fontFamily: iconFont, fontPackage: iconFontPackage);
/// Outlines of 2 overlapping sticker tags.
///
/// See also:
///
/// * [tag], similar but with only one tag.
static const IconData tags = IconData(0xf48e, fontFamily: iconFont, fontPackage: iconFontPackage);
/// 2 overlapping sticker tags. This icon is filled in.
///
/// See also:
///
/// * [tag_solid], similar but with only one tag.
static const IconData tags_solid = IconData(0xf48f, fontFamily: iconFont, fontPackage: iconFontPackage);
} }
This diff is collapsed.
...@@ -20,14 +20,16 @@ const double _kToolbarHeight = 36.0; ...@@ -20,14 +20,16 @@ const double _kToolbarHeight = 36.0;
const Color _kToolbarBackgroundColor = Color(0xFF2E2E2E); const Color _kToolbarBackgroundColor = Color(0xFF2E2E2E);
const Color _kToolbarDividerColor = Color(0xFFB9B9B9); const Color _kToolbarDividerColor = Color(0xFFB9B9B9);
const Color _kHandlesColor = Color(0xFF146DDE); // Read off from the output on iOS 12. This color does not vary with the
// application's theme color.
const Color _kHandlesColor = Color(0xFF136FE0);
// This offset is used to determine the center of the selection during a drag. // This offset is used to determine the center of the selection during a drag.
// It's slightly below the center of the text so the finger isn't entirely // It's slightly below the center of the text so the finger isn't entirely
// covering the text being selected. // covering the text being selected.
const Size _kSelectionOffset = Size(20.0, 30.0); const Size _kSelectionOffset = Size(20.0, 30.0);
const Size _kToolbarTriangleSize = Size(18.0, 9.0); const Size _kToolbarTriangleSize = Size(18.0, 9.0);
const EdgeInsets _kToolbarButtonPadding = EdgeInsets.symmetric(vertical: 10.0, horizontal: 21.0); const EdgeInsets _kToolbarButtonPadding = EdgeInsets.symmetric(vertical: 10.0, horizontal: 18.0);
const BorderRadius _kToolbarBorderRadius = BorderRadius.all(Radius.circular(7.5)); const BorderRadius _kToolbarBorderRadius = BorderRadius.all(Radius.circular(7.5));
const TextStyle _kToolbarButtonFontStyle = TextStyle( const TextStyle _kToolbarButtonFontStyle = TextStyle(
...@@ -121,6 +123,7 @@ class _TextSelectionToolbar extends StatelessWidget { ...@@ -121,6 +123,7 @@ class _TextSelectionToolbar extends StatelessWidget {
// avoid letting the triangle line up with any dividers. // avoid letting the triangle line up with any dividers.
// https://github.com/flutter/flutter/issues/11274 // https://github.com/flutter/flutter/issues/11274
triangle, triangle,
const Padding(padding: EdgeInsets.only(bottom: 10.0)),
], ],
); );
} }
......
...@@ -154,10 +154,7 @@ class TextField extends StatefulWidget { ...@@ -154,10 +154,7 @@ class TextField extends StatefulWidget {
/// extra padding introduced by the decoration to save space for the labels). /// extra padding introduced by the decoration to save space for the labels).
final InputDecoration decoration; final InputDecoration decoration;
/// The type of keyboard to use for editing the text. /// {@macro flutter.widgets.editableText.keyboardType}
///
/// Defaults to [TextInputType.text] if [maxLines] is one and
/// [TextInputType.multiline] otherwise.
final TextInputType keyboardType; final TextInputType keyboardType;
/// The type of action button to use for the keyboard. /// The type of action button to use for the keyboard.
...@@ -166,17 +163,7 @@ class TextField extends StatefulWidget { ...@@ -166,17 +163,7 @@ class TextField extends StatefulWidget {
/// [TextInputType.multiline] and [TextInputAction.done] otherwise. /// [TextInputType.multiline] and [TextInputAction.done] otherwise.
final TextInputAction textInputAction; final TextInputAction textInputAction;
/// Configures how the platform keyboard will select an uppercase or /// {@macro flutter.widgets.editableText.textCapitalization}
/// lowercase keyboard.
///
/// Only supports text keyboards, other keyboard types will ignore this
/// configuration. Capitalization is locale-aware.
///
/// Defaults to [TextCapitalization.none]. Must not be null.
///
/// See also:
///
/// * [TextCapitalization], for a description of each capitalization behavior.
final TextCapitalization textCapitalization; final TextCapitalization textCapitalization;
/// The style to use for the text being edited. /// The style to use for the text being edited.
...@@ -186,42 +173,19 @@ class TextField extends StatefulWidget { ...@@ -186,42 +173,19 @@ class TextField extends StatefulWidget {
/// If null, defaults to the `subhead` text style from the current [Theme]. /// If null, defaults to the `subhead` text style from the current [Theme].
final TextStyle style; final TextStyle style;
/// How the text being edited should be aligned horizontally. /// {@macro flutter.widgets.editableText.textAlign}
///
/// Defaults to [TextAlign.start].
final TextAlign textAlign; final TextAlign textAlign;
/// Whether this text field should focus itself if nothing else is already /// {@macro flutter.widgets.editableText.autofocus}
/// focused.
///
/// If true, the keyboard will open as soon as this text field obtains focus.
/// Otherwise, the keyboard is only shown after the user taps the text field.
///
/// Defaults to false. Cannot be null.
// See https://github.com/flutter/flutter/issues/7035 for the rationale for this
// keyboard behavior.
final bool autofocus; final bool autofocus;
/// Whether to hide the text being edited (e.g., for passwords). /// {@macro flutter.widgets.editableText.obscureText}
///
/// When this is set to true, all the characters in the text field are
/// replaced by U+2022 BULLET characters (•).
///
/// Defaults to false. Cannot be null.
final bool obscureText; final bool obscureText;
/// Whether to enable autocorrection. /// {@macro flutter.widgets.editableText.autocorrect}
///
/// Defaults to true. Cannot be null.
final bool autocorrect; final bool autocorrect;
/// The maximum number of lines for the text to span, wrapping if necessary. /// {@macro flutter.widgets.editableText.maxLines}
///
/// If this is 1 (the default), the text will not wrap, but will scroll
/// horizontally instead.
///
/// If this is null, there is no limit to the number of lines. If it is not
/// null, the value must be greater than zero.
final int maxLines; final int maxLines;
/// The maximum number of characters (Unicode scalar values) to allow in the /// The maximum number of characters (Unicode scalar values) to allow in the
...@@ -280,34 +244,16 @@ class TextField extends StatefulWidget { ...@@ -280,34 +244,16 @@ class TextField extends StatefulWidget {
/// [maxLength] is exceeded. /// [maxLength] is exceeded.
final bool maxLengthEnforced; final bool maxLengthEnforced;
/// Called when the text being edited changes. /// {@macro flutter.widgets.editableText.onChanged}
final ValueChanged<String> onChanged; final ValueChanged<String> onChanged;
/// Called when the user submits editable content (e.g., user presses the "done" /// {@macro flutter.widgets.editableText.onEditingComplete}
/// button on the keyboard).
///
/// The default implementation of [onEditingComplete] executes 2 different
/// behaviors based on the situation:
///
/// - When a completion action is pressed, such as "done", "go", "send", or
/// "search", the user's content is submitted to the [controller] and then
/// focus is given up.
///
/// - When a non-completion action is pressed, such as "next" or "previous",
/// the user's content is submitted to the [controller], but focus is not
/// given up because developers may want to immediately move focus to
/// another input widget within [onSubmitted].
///
/// Providing [onEditingComplete] prevents the aforementioned default behavior.
final VoidCallback onEditingComplete; final VoidCallback onEditingComplete;
/// Called when the user indicates that they are done editing the text in the /// {@macro flutter.widgets.editableText.onSubmitted}
/// field.
final ValueChanged<String> onSubmitted; final ValueChanged<String> onSubmitted;
/// Optional input validation and formatting overrides. /// {@macro flutter.widgets.editableText.inputFormatters}
///
/// Formatters are run in the provided order when the text input changes.
final List<TextInputFormatter> inputFormatters; final List<TextInputFormatter> inputFormatters;
/// If false the textfield is "disabled": it ignores taps and its /// If false the textfield is "disabled": it ignores taps and its
...@@ -317,16 +263,15 @@ class TextField extends StatefulWidget { ...@@ -317,16 +263,15 @@ class TextField extends StatefulWidget {
/// [Decoration.enabled] property. /// [Decoration.enabled] property.
final bool enabled; final bool enabled;
/// How thick the cursor will be. /// {@macro flutter.widgets.editableText.cursorWidth}
///
/// Defaults to 2.0.
final double cursorWidth; final double cursorWidth;
/// How rounded the corners of the cursor should be. /// {@macro flutter.widgets.editableText.cursorRadius}
/// By default, the cursor has a null Radius
final Radius cursorRadius; final Radius cursorRadius;
/// The color to use when painting the cursor. /// The color to use when painting the cursor.
///
/// Defaults to the theme's `cursorColor` when null.
final Color cursorColor; final Color cursorColor;
/// The appearance of the keyboard. /// The appearance of the keyboard.
...@@ -336,14 +281,7 @@ class TextField extends StatefulWidget { ...@@ -336,14 +281,7 @@ class TextField extends StatefulWidget {
/// If unset, defaults to the brightness of [ThemeData.primaryColorBrightness]. /// If unset, defaults to the brightness of [ThemeData.primaryColorBrightness].
final Brightness keyboardAppearance; final Brightness keyboardAppearance;
/// Configures padding to edges surrounding a [Scrollable] when the Textfield scrolls into view. /// {@macro flutter.widgets.editableText.scrollPadding}
///
/// When this widget receives focus and is not completely visible (for example scrolled partially
/// off the screen or overlapped by the keyboard)
/// then it will attempt to make itself visible by scrolling a surrounding [Scrollable], if one is present.
/// This value controls how far from the edges of a [Scrollable] the TextField will be positioned after the scroll.
///
/// Defaults to EdgeInserts.all(20.0).
final EdgeInsets scrollPadding; final EdgeInsets scrollPadding;
/// {@macro flutter.widgets.editableText.enableInteractiveSelection} /// {@macro flutter.widgets.editableText.enableInteractiveSelection}
......
...@@ -242,22 +242,31 @@ class EditableText extends StatefulWidget { ...@@ -242,22 +242,31 @@ class EditableText extends StatefulWidget {
/// Controls whether this widget has keyboard focus. /// Controls whether this widget has keyboard focus.
final FocusNode focusNode; final FocusNode focusNode;
/// {@template flutter.widgets.editableText.obscureText}
/// Whether to hide the text being edited (e.g., for passwords). /// Whether to hide the text being edited (e.g., for passwords).
/// ///
/// Defaults to false. /// When this is set to true, all the characters in the text field are
/// replaced by U+2022 BULLET characters (•).
///
/// Defaults to false. Cannot be null.
/// {@endtemplate}
final bool obscureText; final bool obscureText;
/// {@template flutter.widgets.editableText.autocorrect}
/// Whether to enable autocorrection. /// Whether to enable autocorrection.
/// ///
/// Defaults to true. /// Defaults to true. Cannot be null.
/// {@endtemplate}
final bool autocorrect; final bool autocorrect;
/// The text style to use for the editable text. /// The text style to use for the editable text.
final TextStyle style; final TextStyle style;
/// {@template flutter.widgets.editableText.textAlign}
/// How the text should be aligned horizontally. /// How the text should be aligned horizontally.
/// ///
/// Defaults to [TextAlign.start]. /// Defaults to [TextAlign.start] and cannot be null.
/// {@endtemplate}
final TextAlign textAlign; final TextAlign textAlign;
/// The directionality of the text. /// The directionality of the text.
...@@ -275,6 +284,7 @@ class EditableText extends StatefulWidget { ...@@ -275,6 +284,7 @@ class EditableText extends StatefulWidget {
/// Defaults to the ambient [Directionality], if any. /// Defaults to the ambient [Directionality], if any.
final TextDirection textDirection; final TextDirection textDirection;
/// {@template flutter.widgets.editableText.textCapitalization}
/// Configures how the platform keyboard will select an uppercase or /// Configures how the platform keyboard will select an uppercase or
/// lowercase keyboard. /// lowercase keyboard.
/// ///
...@@ -286,6 +296,7 @@ class EditableText extends StatefulWidget { ...@@ -286,6 +296,7 @@ class EditableText extends StatefulWidget {
/// See also: /// See also:
/// ///
/// * [TextCapitalization], for a description of each capitalization behavior. /// * [TextCapitalization], for a description of each capitalization behavior.
/// {@endtemplate}
final TextCapitalization textCapitalization; final TextCapitalization textCapitalization;
/// Used to select a font when the same Unicode character can /// Used to select a font when the same Unicode character can
...@@ -307,8 +318,11 @@ class EditableText extends StatefulWidget { ...@@ -307,8 +318,11 @@ class EditableText extends StatefulWidget {
final double textScaleFactor; final double textScaleFactor;
/// The color to use when painting the cursor. /// The color to use when painting the cursor.
///
/// Cannot be null.
final Color cursorColor; final Color cursorColor;
/// {@template flutter.widgets.editableText.maxLines}
/// The maximum number of lines for the text to span, wrapping if necessary. /// The maximum number of lines for the text to span, wrapping if necessary.
/// ///
/// If this is 1 (the default), the text will not wrap, but will scroll /// If this is 1 (the default), the text will not wrap, but will scroll
...@@ -316,13 +330,20 @@ class EditableText extends StatefulWidget { ...@@ -316,13 +330,20 @@ class EditableText extends StatefulWidget {
/// ///
/// If this is null, there is no limit to the number of lines. If it is not /// If this is null, there is no limit to the number of lines. If it is not
/// null, the value must be greater than zero. /// null, the value must be greater than zero.
/// {@endtemplate}
final int maxLines; final int maxLines;
/// Whether this input field should focus itself if nothing else is already focused. /// {@template flutter.widgets.editableText.autofocus}
/// If true, the keyboard will open as soon as this input obtains focus. Otherwise, /// Whether this text field should focus itself if nothing else is already
/// the keyboard is only shown after the user taps the text field. /// focused.
///
/// If true, the keyboard will open as soon as this text field obtains focus.
/// Otherwise, the keyboard is only shown after the user taps the text field.
/// ///
/// Defaults to false. /// Defaults to false. Cannot be null.
/// {@endtemplate}
// See https://github.com/flutter/flutter/issues/7035 for the rationale for this
// keyboard behavior.
final bool autofocus; final bool autofocus;
/// The color to use when painting the selection. /// The color to use when painting the selection.
...@@ -331,15 +352,23 @@ class EditableText extends StatefulWidget { ...@@ -331,15 +352,23 @@ class EditableText extends StatefulWidget {
/// Optional delegate for building the text selection handles and toolbar. /// Optional delegate for building the text selection handles and toolbar.
final TextSelectionControls selectionControls; final TextSelectionControls selectionControls;
/// {@template flutter.widgets.editableText.keyboardType}
/// The type of keyboard to use for editing the text. /// The type of keyboard to use for editing the text.
///
/// Defaults to [TextInputType.text] if [maxLines] is one and
/// [TextInputType.multiline] otherwise.
/// {@endtemplate}
final TextInputType keyboardType; final TextInputType keyboardType;
/// The type of action button to use with the soft keyboard. /// The type of action button to use with the soft keyboard.
final TextInputAction textInputAction; final TextInputAction textInputAction;
/// {@template flutter.widgets.editableText.onChanged}
/// Called when the text being edited changes. /// Called when the text being edited changes.
/// {@endtemplate}
final ValueChanged<String> onChanged; final ValueChanged<String> onChanged;
/// {@template flutter.widgets.editableText.onEditingComplete}
/// Called when the user submits editable content (e.g., user presses the "done" /// Called when the user submits editable content (e.g., user presses the "done"
/// button on the keyboard). /// button on the keyboard).
/// ///
...@@ -356,17 +385,24 @@ class EditableText extends StatefulWidget { ...@@ -356,17 +385,24 @@ class EditableText extends StatefulWidget {
/// another input widget within [onSubmitted]. /// another input widget within [onSubmitted].
/// ///
/// Providing [onEditingComplete] prevents the aforementioned default behavior. /// Providing [onEditingComplete] prevents the aforementioned default behavior.
/// {@endtemplate}
final VoidCallback onEditingComplete; final VoidCallback onEditingComplete;
/// Called when the user indicates that they are done editing the text in the field. /// {@template flutter.widgets.editableText.onSubmitted}
/// Called when the user indicates that they are done editing the text in the
/// field.
/// {@endtemplate}
final ValueChanged<String> onSubmitted; final ValueChanged<String> onSubmitted;
/// Called when the user changes the selection of text (including the cursor /// Called when the user changes the selection of text (including the cursor
/// location). /// location).
final SelectionChangedCallback onSelectionChanged; final SelectionChangedCallback onSelectionChanged;
/// Optional input validation and formatting overrides. Formatters are run /// {@template flutter.widgets.editableText.inputFormatters}
/// in the provided order when the text input changes. /// Optional input validation and formatting overrides.
///
/// Formatters are run in the provided order when the text input changes.
/// {@endtemplate}
final List<TextInputFormatter> inputFormatters; final List<TextInputFormatter> inputFormatters;
/// If true, the [RenderEditable] created by this widget will not handle /// If true, the [RenderEditable] created by this widget will not handle
...@@ -375,14 +411,18 @@ class EditableText extends StatefulWidget { ...@@ -375,14 +411,18 @@ class EditableText extends StatefulWidget {
/// This property is false by default. /// This property is false by default.
final bool rendererIgnoresPointer; final bool rendererIgnoresPointer;
/// {@template flutter.widgets.editableText.cursorWidth}
/// How thick the cursor will be. /// How thick the cursor will be.
/// ///
/// Defaults to 2.0 /// Defaults to 2.0
/// {@endtemplate}
final double cursorWidth; final double cursorWidth;
/// {@template flutter.widgets.editableText.cursorRadius}
/// How rounded the corners of the cursor should be. /// How rounded the corners of the cursor should be.
/// ///
/// By default, the cursor has a Radius of zero. /// By default, the cursor has no radius.
/// {@endtemplate}
final Radius cursorRadius; final Radius cursorRadius;
/// The appearance of the keyboard. /// The appearance of the keyboard.
...@@ -392,6 +432,7 @@ class EditableText extends StatefulWidget { ...@@ -392,6 +432,7 @@ class EditableText extends StatefulWidget {
/// Defaults to [Brightness.light]. /// Defaults to [Brightness.light].
final Brightness keyboardAppearance; final Brightness keyboardAppearance;
/// {@template flutter.widgets.editableText.scrollPadding}
/// Configures padding to edges surrounding a [Scrollable] when the Textfield scrolls into view. /// Configures padding to edges surrounding a [Scrollable] when the Textfield scrolls into view.
/// ///
/// When this widget receives focus and is not completely visible (for example scrolled partially /// When this widget receives focus and is not completely visible (for example scrolled partially
...@@ -400,6 +441,7 @@ class EditableText extends StatefulWidget { ...@@ -400,6 +441,7 @@ class EditableText extends StatefulWidget {
/// This value controls how far from the edges of a [Scrollable] the TextField will be positioned after the scroll. /// This value controls how far from the edges of a [Scrollable] the TextField will be positioned after the scroll.
/// ///
/// Defaults to EdgeInserts.all(20.0). /// Defaults to EdgeInserts.all(20.0).
/// {@endtemplate}
final EdgeInsets scrollPadding; final EdgeInsets scrollPadding;
/// {@template flutter.widgets.editableText.enableInteractiveSelection} /// {@template flutter.widgets.editableText.enableInteractiveSelection}
......
...@@ -531,6 +531,9 @@ class _TextSelectionHandleOverlayState extends State<_TextSelectionHandleOverlay ...@@ -531,6 +531,9 @@ class _TextSelectionHandleOverlayState extends State<_TextSelectionHandleOverlay
onPanUpdate: _handleDragUpdate, onPanUpdate: _handleDragUpdate,
onTap: _handleTap, onTap: _handleTap,
child: Stack( child: Stack(
// Always let the selection handles draw outside of the conceptual
// box where (0,0) is the top left corner of the RenderEditable.
overflow: Overflow.visible,
children: <Widget>[ children: <Widget>[
Positioned( Positioned(
left: point.dx, left: point.dx,
......
This diff is collapsed.
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