How to Trigger a Function with the Enter Key in Flutter (Even When Unfocused)

Do you need to trigger a specific action in your Flutter app when the user presses the Enter key, regardless of whether a text field is currently focused? This article provides a practical solution to achieve this behavior, enabling a more intuitive user experience.

The Problem: Detecting Enter Key Presses Outside of Text Fields

Flutter’s built-in text field functionalities, like onSubmitted, only work when a text field is actively focused. The challenge lies in detecting Enter key presses when no text field has focus, allowing you to trigger actions based on a global key press.

The Solution: Using FocusScope and Key Event Handling

The most effective approach involves wrapping your relevant UI elements within a FocusScope and utilizing its onKeyEvent property to listen for key presses. This allows you to capture the Enter key event even when no specific text field is in focus.

Step-by-Step Implementation

  1. Wrap Your UI: Enclose the relevant part of your UI (e.g., your entire dialog or screen) within a FocusScope widget.

    
     FocusScope(
      node: _focusScopeNode,
      autofocus: true,
      onKeyEvent: _handleKeyEvent,
      child: // Your UI elements here
     )
     
  2. Create a FocusScopeNode: Declare a FocusScopeNode in your widget’s state.

    
     final FocusScopeNode _focusScopeNode = FocusScopeNode();
     
  3. Implement the Key Event Handler: Define a function to handle the onKeyEvent event. This function will check for the Enter key press and trigger your desired action.

    
     KeyEventResult _handleKeyEvent(FocusNode node, KeyEvent event) {
      if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) {
       if (_focusScopeNode.focusedChild == null) {
        // No text field is focused, trigger your function here!
        _yourFunctionToCall();
        return KeyEventResult.handled; // Indicate that the event is handled
       } else {
        // A text field is focused, you might want to unfocus it.
        _focusScopeNode.unfocus();
        return KeyEventResult.handled;
       }
      }
      return KeyEventResult.ignored; // Let Flutter handle other key events
     }
     
  4. Add TextFields and Control Submission: Add the text fields to your UI, and use FocusNodes to handle the submission of text values and clearing the focus.

    
        TextField(
         focusNode: _textFieldFocusNode,
         onSubmitted: (_) {
           _textFieldFocusNode.unfocus();
           _yourFunctionToCallWithSubmittedValue(_);
         },
        ),
       
  5. Implement the Function: Define the function that will be triggered when the Enter key is pressed and no text field is focused.

    
       Future _yourFunctionToCall() async {
         // Your logic goes here (e.g., submitting a form, performing a search)
         print("Enter key pressed and no textfield is focused!");
       }
    
       Future _yourFunctionToCallWithSubmittedValue(String value) async {
         // Your logic goes here (e.g., submitting a form, performing a search)
         print("Enter key pressed on textfield with Value: $value !");
       }
    
       

Complete Example


 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';

 void main() {
  runApp(MyApp());
 }

 class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
   return MaterialApp(
    title: 'Enter Key Demo',
    home: MyHomePage(),
   );
  }
 }

 class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
 }

 class _MyHomePageState extends State {
  final FocusScopeNode _focusScopeNode = FocusScopeNode();
  final FocusNode _textFieldFocusNode = FocusNode();

  KeyEventResult _handleKeyEvent(FocusNode node, KeyEvent event) {
   if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) {
    if (_focusScopeNode.focusedChild == null) {
     // No text field is focused, trigger your function here!
     _yourFunctionToCall();
     return KeyEventResult.handled; // Indicate that the event is handled
    } else {
     // A text field is focused, you might want to unfocus it.
     _focusScopeNode.unfocus();
     return KeyEventResult.handled;
    }
   }
   return KeyEventResult.ignored; // Let Flutter handle other key events
  }

  Future _yourFunctionToCall() async {
   // Your logic goes here (e.g., submitting a form, performing a search)
   print("Enter key pressed and no textfield is focused!");
  }

  Future _yourFunctionToCallWithSubmittedValue(String value) async {
   // Your logic goes here (e.g., submitting a form, performing a search)
   print("Enter key pressed on textfield with Value: $value !");
  }

  @override
  Widget build(BuildContext context) {
   return Scaffold(
    appBar: AppBar(
     title: Text('Enter Key Demo'),
    ),
    body: FocusScope(
     node: _focusScopeNode,
     autofocus: true,
     onKeyEvent: _handleKeyEvent,
     child: Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
       children: [
        TextField(
         focusNode: _textFieldFocusNode,
         onSubmitted: (_) {
           _textFieldFocusNode.unfocus();
           _yourFunctionToCallWithSubmittedValue(_);
         },
         decoration: InputDecoration(
          labelText: 'Enter some text',
          border: OutlineInputBorder(),
         ),
        ),
        SizedBox(height: 20),
        ElevatedButton(
         onPressed: () {
          // Example button. You can click and then press enter when button is focused.
          print("Button pressed");
         },
         child: Text("Do Something"),
        ),
       ],
      ),
     ),
    ),
   );
  }
 }
 

Possible Issues and Solutions

  • KeyEventResult.handled interfering with other widgets: If setting KeyEventResult.handled prevents other widgets from receiving key events, try using KeyEventResult.skipRemainingHandlers to allow other handlers to process the event after yours. However KeyEventResult.ignored may be better suited.
  • Text input is not working after implementing it: You may need to set to return KeyEventResult.ignored; so the system understand the key is not handled and pass it deeper to the text fields.
  • Async functions: Make sure if you are calling an async function is called correctly, use var isAsyncRunning to handle that function is still running.

Conclusion

By utilizing FocusScope and key event handling, you can effectively capture Enter key presses in Flutter, even when no text field is focused. This approach provides a flexible and robust solution for implementing custom keyboard interactions in your applications, enhancing the user experience.