Search code examples
keyboardtextfieldflutter

How to detect when a TextField is selected in Flutter?


I have a Flutter TextField which gets covered by the soft keyboard when the field is selected. I need to scroll the field up and out of the way when the keyboard is displayed. This is a pretty common problem and a solution is presented in this StackOverflow post.

I think I have the ScrollController part figured out but how do I detect when the TextField has been selected? There doesn't appear to be any event method (e.g. onFocus(), onSelected(), onTap(), etc).

I tried wrapping the TextField in a GestureDetector but that didn't work either -- apparently the event was never captured.

new GestureDetector(
  child: new TextField(
    decoration: const InputDecoration(labelText: 'City'),
  ),
  onTap: () => print('Text Selected'),
),

This is such a basic requirement that I know there must be an easy solution.


Solution

  • I suppose you are looking for FocusNode.

    To listen to focus change, you can add a listner to the FocusNode and specify the focusNode to TextField.

    Example:

    class TextFieldFocus extends StatefulWidget {
      @override
      _TextFieldFocusState createState() => _TextFieldFocusState();
    }
    
    class _TextFieldFocusState extends State<TextFieldFocus> {
      FocusNode _focus = FocusNode();
    
      TextEditingController _controller = TextEditingController();
    
      @override
      void initState() {
        super.initState();
        _focus.addListener(_onFocusChange);
      }
    
      @override
      void dispose() {
        super.dispose();
        _focus.removeListener(_onFocusChange);
        _focus.dispose();
      }
    
      void _onFocusChange() {
        debugPrint("Focus: ${_focus.hasFocus.toString()}");
      }
      
      @override
      Widget build(BuildContext context) {
        return new Container(
          color: Colors.white,
          child: new TextField(
            focusNode: _focus,
          ),
        );
      }
    }
    

    This gist represents how to ensure a focused node to be visible on the ui.