How to prevent keyboard from dismissing on pressing submit key in flutter?
TextField
widget has a parameter just for this purpose!
While onSubmit
callback can be used to handle business logic when the user presses done, there is also a property called onEditingComplete
, specially made to handle focus-related logic. So you should use both, for better code readability.
According to the docs:
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.
Therefore, if you don't like this behaviour, for example, "send" is considered a "completion action" here, thus in an Instant Messaging (chatting) app, each time user sends a short message, the keyboard will be collapsed. But if we override the onEditingComplete
callback to an empty function, it will stop the default behavior and not hide the keyboard.
Sample code:
TextField(
controller: _controller,
onSubmitted: (value) {
sendMessage(text);
_controller.clear();
},
onEditingComplete: () {}, // this prevents keyboard from closing
textInputAction: TextInputAction.send,
)
Demo:
For complete explanation and comparison between onSubmitted
and onEditingComplete
callbacks, check out my other answer here.
This worked for me:-
First Create a FocusNode
and assign it to your textfield, do the following :-
The FocusNode
is a long lived component so initialize it in the initState
method:-
FocusNode inputFieldNode;
@override
void initState() {
super.initState();
inputFieldNode = FocusNode();
}
Do not forget to cleanup the FocusNode
in dispose
method after the Form is disposed:-
@override
void dispose() {
inputFieldNode.dispose();
super.dispose();
}
Assign the FocusNode
to the textfield and write the following code in onSubmitted:
:-
TextField(
focusNode: inputFieldNode,
onSubmitted: (String) => FocusScope.of(context).requestFocus(inputFieldNode),
)
Now the textfield will not lose focus even after pressing the submit button.
The cleanest approach would be to use onEditingComplete() with TextEditingController instead of onSubmitted(text). Refer below example.
final _controller = TextEditingController();
TextField(
controller: _controller,
padding: EdgeInsets.all(8),
textInputAction: TextInputAction.send,
placeholder: 'Type your message',
onEditingComplete: (){
if (_controller.text.isEmpty) return;
sendMessage(_controller.text);
},
),