From e8fbdd85f02108db66688fde41ded773ee03b7a7 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Thu, 11 Jul 2019 07:56:30 -0700 Subject: [PATCH] Add example showing how to move from one field to the next. (#35926) This adds an example of how to move to the "next" field when using TextInputAction.next. This is all that is needed to have "next field" functionality in a field. I thought about making it the default when handling the "next" or "previous" actions, but it's better that the developer has control over whether or not they actually move to the next field, and within which scope. --- .../flutter/lib/src/cupertino/text_field.dart | 6 ++ .../flutter/lib/src/material/text_field.dart | 6 ++ .../lib/src/widgets/editable_text.dart | 59 ++++++++++++++++++- 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/cupertino/text_field.dart b/packages/flutter/lib/src/cupertino/text_field.dart index 3c357f1d20..6a77c118ab 100644 --- a/packages/flutter/lib/src/cupertino/text_field.dart +++ b/packages/flutter/lib/src/cupertino/text_field.dart @@ -411,6 +411,12 @@ class CupertinoTextField extends StatefulWidget { final VoidCallback onEditingComplete; /// {@macro flutter.widgets.editableText.onSubmitted} + /// + /// See also: + /// + /// * [EditableText.onSubmitted] for an example of how to handle moving to + /// the next/previous field when using [TextInputAction.next] and + /// [TextInputAction.previous] for [textInputAction]. final ValueChanged onSubmitted; /// {@macro flutter.widgets.editableText.inputFormatters} diff --git a/packages/flutter/lib/src/material/text_field.dart b/packages/flutter/lib/src/material/text_field.dart index 8b98affeaf..0a1d29a952 100644 --- a/packages/flutter/lib/src/material/text_field.dart +++ b/packages/flutter/lib/src/material/text_field.dart @@ -388,6 +388,12 @@ class TextField extends StatefulWidget { final VoidCallback onEditingComplete; /// {@macro flutter.widgets.editableText.onSubmitted} + /// + /// See also: + /// + /// * [EditableText.onSubmitted] for an example of how to handle moving to + /// the next/previous field when using [TextInputAction.next] and + /// [TextInputAction.previous] for [textInputAction]. final ValueChanged onSubmitted; /// {@macro flutter.widgets.editableText.inputFormatters} diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart index 6cb99d4f79..468b0a834b 100644 --- a/packages/flutter/lib/src/widgets/editable_text.dart +++ b/packages/flutter/lib/src/widgets/editable_text.dart @@ -101,7 +101,7 @@ const int _kObscureShowLatestCharCursorTicks = 3; /// padding: const EdgeInsets.all(6), /// child: TextFormField( /// controller: _controller, -/// decoration: InputDecoration(border: OutlineInputBorder()), +/// decoration: InputDecoration(border: OutlineInputBorder()), /// ), /// ), /// ); @@ -688,6 +688,63 @@ class EditableText extends StatefulWidget { /// Called when the user indicates that they are done editing the text in the /// field. /// {@endtemplate} + /// + /// {@tool snippet --template=stateful_widget_material} + /// When a non-completion action is pressed, such as "next" or "previous", it + /// is often desirable to move the focus to the next or previous field. To do + /// this, handle it as in this example, by calling [FocusNode.focusNext] in + /// the [TextFormField.onFieldSubmitted] callback ([TextFormField] wraps + /// [EditableText] internally, and uses the value of `onFieldSubmitted` as its + /// [onSubmitted]). + /// + /// ```dart + /// FocusScopeNode _focusScopeNode = FocusScopeNode(); + /// final _controller1 = TextEditingController(); + /// final _controller2 = TextEditingController(); + /// + /// void dispose() { + /// _focusScopeNode.dispose(); + /// _controller1.dispose(); + /// _controller2.dispose(); + /// super.dispose(); + /// } + /// + /// void _handleSubmitted(String value) { + /// _focusScopeNode.nextFocus(); + /// } + /// + /// Widget build(BuildContext context) { + /// return Scaffold( + /// body: FocusScope( + /// node: _focusScopeNode, + /// child: Column( + /// mainAxisAlignment: MainAxisAlignment.center, + /// children: [ + /// Padding( + /// padding: const EdgeInsets.all(8.0), + /// child: TextFormField( + /// textInputAction: TextInputAction.next, + /// onFieldSubmitted: _handleSubmitted, + /// controller: _controller1, + /// decoration: InputDecoration(border: OutlineInputBorder()), + /// ), + /// ), + /// Padding( + /// padding: const EdgeInsets.all(8.0), + /// child: TextFormField( + /// textInputAction: TextInputAction.next, + /// onFieldSubmitted: _handleSubmitted, + /// controller: _controller2, + /// decoration: InputDecoration(border: OutlineInputBorder()), + /// ), + /// ), + /// ], + /// ), + /// ), + /// ); + /// } + /// ``` + /// {@end-tool} final ValueChanged onSubmitted; /// Called when the user changes the selection of text (including the cursor