flutterfocusautofocus

Flutter TextFormField, focusNode.requestFocus works once then keyboard doesn't show


Goal: when send button is pressed, don't close the keyboard and keep it open/focused Problem: when send button is pressed, keyboard is closed, then reopens because of focusNode.requestFocus, when send button is pressed after that, the keyboard doesn't open anymore Looking for two options:

  1. (ideal) Don't let the keyboard close when send button is pressed
  2. (okay) Open keyboard no matter how many times send button is closed

Here is sample UI:

return Form(
  key: _formKey,
  child: Row(
    children: <Widget>[
      Expanded(
        child: TextFormField(
          focusNode: chatController.focusNode,
          // textInputAction: TextInputAction.none, // didn't help
          // onEditingComplete: () {}, // didn't help
        )
      ),

      IconButton(
        icon: const Icon(Icons.send),
        onPressed: () async {
          SystemChannels.textInput
              .invokeMethod('TextInput.hide');
          if (_formKey.currentState!.validate()) {
            await chatController.sendMessage(context);
          }
        }
      ),
    ],
  )
);

Here is controller:

late FocusNode focusNode;

@override
void onReady() async { // tried onInit as well
  focusNode = FocusNode();
  super.onReady();
}

void sendMessage(BuildContext context) async {
  // focusNode.unfocus(); // didn't help
  // focusNode2.requestFocus(); // tried to give focus to another widget and take it back, but didn't help
  final a1 = focusNode.hasFocus; // except the very first call, this is true even when focusNode.unfocus() is called

  // neither of these work the second time
  focusNode.requestFocus();
  // FocusScope.of(context).requestFocus(focusNode);
}

I was able to trace code and when second call gets to focus manager here this condition is always true:

if (hasPrimaryFocus && (_manager!._markedForFocus == null || _manager!._markedForFocus == this)) {

even though the keyboard is closed, and it returns without attempting to open the keyboard again


Solution

  • You have a stray:

    SystemChannels.textInput.invokeMethod('TextInput.hide');
    

    in your IconButton callback, it should work after removing it.