Search code examples
flutterflutter-textformfield

How can I catch event when a text field is exiting focus (on blur) in Flutter?


I look into TextFormField, the fields here isn't what I need:

  • onChanged (called after each key pressed, I need when the user has already complete and exit the TextFormField focus)
  • onEditingComplete (called after user press on Done key or similar, but user may exit TextFormField focus without tapping those button)
  • onSave (called after calling form.save(). But I need to do this after user finish editing, to let user know that the app does "auto-correcting" to what the user entered)
  • validator (also called on form.validate(), right before form.save(). not what I needed)

I need that when user exit the focus (dismissing the keyboard or tapping into another text field), I do a processing to let user see that their input is being adjusted and processed to the "correct one". How can I catch such event?


Solution

  • By using FocusNode class, you add a focus listener and can catch focus change.

    By using Focus class, you just wrap TextField and add a onFocusChange parameter.

    [Solution 1]

    • add a define FocusNode instance
    FocusNode focusNode = FocusNode();
    
    • add a listener of FocusNode at initState.
    focusNode.addListener(() {
          print('1:  ${focusNode.hasFocus}');
        });
    
    • add a FocusNode instance to TextField's focusNode parameter.
    TextField(
          focusNode: focusNode,
        )
    

    [Solution 2]

    • Wrap TextField by Focus widget
    Focus(
      child: TextField(),
      onFocusChange: (hasFocus) {
        print('2:  $hasFocus');
      },
    )
    

    [Example Full Code]

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      FocusNode focusNode = FocusNode();
      @override
      void initState() {
        super.initState();
        focusNode.addListener(() {
          print(focusNode.hasFocus);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: _buildBody(),
        );
      }
    
      Widget _buildBody() {
        return TextField(
          focusNode: focusNode,
        );
      }
    }