Commit d556d211 authored by Francisco Magdaleno's avatar Francisco Magdaleno Committed by Greg Spencer

Finalize editing when hitting the enter key on a single line TextField (#23015)

Behavior remains the same for multiline TextFields. This behavior already happens on iOS and Android, but not desktop. #23014
parent ffa8a1eb
...@@ -511,44 +511,43 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien ...@@ -511,44 +511,43 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
void performAction(TextInputAction action) { void performAction(TextInputAction action) {
switch (action) { switch (action) {
case TextInputAction.newline: case TextInputAction.newline:
// Do nothing for a "newline" action: the newline is already inserted. // If this is a multiline EditableText, do nothing for a "newline"
// action; The newline is already inserted. Otherwise, finalize
// editing.
if (widget.maxLines == 1)
_finalizeEditing(true);
break; break;
case TextInputAction.done: case TextInputAction.done:
case TextInputAction.go: case TextInputAction.go:
case TextInputAction.send: case TextInputAction.send:
case TextInputAction.search: case TextInputAction.search:
// Take any actions necessary now that the user has completed editing. _finalizeEditing(true);
if (widget.onEditingComplete != null) {
widget.onEditingComplete();
} else {
// Default behavior if the developer did not provide an
// onEditingComplete callback: Finalize editing and remove focus.
widget.controller.clearComposing();
widget.focusNode.unfocus();
}
// Invoke optional callback with the user's submitted content.
if (widget.onSubmitted != null)
widget.onSubmitted(_value.text);
break; break;
default: default:
if (widget.onEditingComplete != null) { // Finalize editing, but don't give up focus because this keyboard
widget.onEditingComplete(); // action does not imply the user is done inputting information.
} else { _finalizeEditing(false);
// Default behavior if the developer did not provide an
// onEditingComplete callback: Finalize editing, but don't give up
// focus because this keyboard action does not imply the user is done
// inputting information.
widget.controller.clearComposing();
}
// Invoke optional callback with the user's submitted content.
if (widget.onSubmitted != null)
widget.onSubmitted(_value.text);
break; break;
} }
} }
void _finalizeEditing(bool shouldUnfocus) {
// Take any actions necessary now that the user has completed editing.
if (widget.onEditingComplete != null) {
widget.onEditingComplete();
} else {
// Default behavior if the developer did not provide an
// onEditingComplete callback: Finalize editing and remove focus.
widget.controller.clearComposing();
if (shouldUnfocus)
widget.focusNode.unfocus();
}
// Invoke optional callback with the user's submitted content.
if (widget.onSubmitted != null)
widget.onSubmitted(_value.text);
}
void _updateRemoteEditingValueIfNeeded() { void _updateRemoteEditingValueIfNeeded() {
if (!_hasInputConnection) if (!_hasInputConnection)
return; return;
......
...@@ -745,6 +745,94 @@ void main() { ...@@ -745,6 +745,94 @@ void main() {
// and onSubmission callbacks. // and onSubmission callbacks.
}); });
testWidgets(
'When "newline" action is called on a Editable text with maxLines == 1 callbacks are invoked: onEditingComplete > onSubmitted',
(WidgetTester tester) async {
final GlobalKey<EditableTextState> editableTextKey =
GlobalKey<EditableTextState>();
final FocusNode focusNode = FocusNode();
bool onEditingCompleteCalled = false;
bool onSubmittedCalled = false;
final Widget widget = MaterialApp(
home: EditableText(
key: editableTextKey,
controller: TextEditingController(),
focusNode: focusNode,
style: Typography(platform: TargetPlatform.android).black.subhead,
cursorColor: Colors.blue,
maxLines: 1,
onEditingComplete: () {
onEditingCompleteCalled = true;
assert(!onSubmittedCalled);
},
onSubmitted: (String value) {
onSubmittedCalled = true;
assert(onEditingCompleteCalled);
},
),
);
await tester.pumpWidget(widget);
// Select EditableText to give it focus.
final Finder textFinder = find.byKey(editableTextKey);
await tester.tap(textFinder);
await tester.pump();
assert(focusNode.hasFocus);
// The execution path starting with receiveAction() will trigger the
// onEditingComplete and onSubmission callbacks.
await tester.testTextInput.receiveAction(TextInputAction.newline);
// The expectations we care about are up above in the onEditingComplete
// and onSubmission callbacks.
});
testWidgets(
'When "newline" action is called on a Editable text with maxLines != 1, onEditingComplete and onSubmitted callbacks are not invoked.',
(WidgetTester tester) async {
final GlobalKey<EditableTextState> editableTextKey =
GlobalKey<EditableTextState>();
final FocusNode focusNode = FocusNode();
bool onEditingCompleteCalled = false;
bool onSubmittedCalled = false;
final Widget widget = MaterialApp(
home: EditableText(
key: editableTextKey,
controller: TextEditingController(),
focusNode: focusNode,
style: Typography(platform: TargetPlatform.android).black.subhead,
cursorColor: Colors.blue,
maxLines: 3,
onEditingComplete: () {
onEditingCompleteCalled = true;
},
onSubmitted: (String value) {
onSubmittedCalled = true;
},
),
);
await tester.pumpWidget(widget);
// Select EditableText to give it focus.
final Finder textFinder = find.byKey(editableTextKey);
await tester.tap(textFinder);
await tester.pump();
assert(focusNode.hasFocus);
// The execution path starting with receiveAction() will trigger the
// onEditingComplete and onSubmission callbacks.
await tester.testTextInput.receiveAction(TextInputAction.newline);
// These callbacks shouldn't have been triggered.
assert(!onSubmittedCalled);
assert(!onEditingCompleteCalled);
});
testWidgets('Changing controller updates EditableText', testWidgets('Changing controller updates EditableText',
(WidgetTester tester) async { (WidgetTester tester) async {
final GlobalKey<EditableTextState> editableTextKey = final GlobalKey<EditableTextState> editableTextKey =
......
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