Flutter: Prevent to call onChange of TextField when Keyboard hide (Back Press)

Issue

I am working on Flutter, Calling API based on Search Parameters.

What I have done is:

  • Search Box created using TextField
  • onChange of that TextField, I have called method to get data from server.
  • ListView displaying a list

Problem: When I hide the keyboard after my searching is done using back press, It’s requesting again to get data.

You can check video for better explanation:

Here is my code:

getTextInputField() {
    return Flexible(
      fit: FlexFit.tight,
      flex: 1,
      child: TextFormField(
        controller: _text,
        decoration: new InputDecoration(
          labelText: "Enter Area for Pincode",
          fillColor: Colors.white,
          errorText: _validateAgain ? 'This should not be empty!' : null,
          border: new OutlineInputBorder(
            borderRadius: new BorderRadius.circular(15.0),
            borderSide: new BorderSide(),
          ),
          //fillColor: Colors.green
        ),
        validator: (val) {
          if (val.length == 0) {
            return "This shouldn't be empty!";
          } else {
            return null;
          }
        },
        onChanged: (value) {
          getData();
        },
        keyboardType: TextInputType.streetAddress,
      ),
    );
  }

getData() {
    setState(() {
      if (_text.text.isNotEmpty) {
        if (_text.text.length > 2) {
          _validateAgain = false;
          textValue = _text.text;
          _apiCall = true;
          _callAPIForPinCode();
        }
      } else
        _validateAgain = true;
    });
  }

How I prevent calling API again when I hide the keyboard using back press.

Note: If I hide the keyboard using the done key from the keyboard, it’s not calling API and hiding smoothly.

Edited:

As I have tested offline right now, It’s calling offline too. It’s calling the event of onChange on dismissing the keyboard.

Solution

keep track of the last searched text and compare newText that arrives from the onChange callback and if they are different then you can execute searchApi function

for example :

class _PageAState extends State<PageA> {
  String lastInputValue;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: TextField(
        onChanged: (inputValue) {
          if (lastInputValue != inputValue) {
            lastInputValue = inputValue;
            print("New value inserted in textField $inputValue");
          }
        },
      ),
    );
  }
}

this code only prints if the value of the text field is actually changed and it’s not reacting to the keyboard changes or other things that can invoke the onChange method

Why This is happening?

it is happening because the range of the text that you were composing is changed this event will happen when you change the cursor between two words that are separated with space when you click on the first one onChange will be invoked and again when you click on the other word onChange callback going to be invoked

you could see SDK source code for EditableTextState and the _formatAndSetValue function at line 2242 this function is responsible for invoking the onChange callback and for this it is receiving a TextEditingValue object which contains information about the changes that are happened in TextField for example it contains text property which refers to the TextFild text after a change or selection property that refers to the which chars are selected by the user and also a TextRange property that refers to the range of text that is still being composed and in the _formatAndSetValue it is checking conditions to invoke the onChangeMethod
The first one is to see if the text differs from the previous TextFiled text and the second one is to check to see if the Composing range differs from the previous Composing range

so when you click on a word in the text field or event empty text
field and keyboard opens up the composing range is changed to that
word or section which you click and when you close the keyboard
composing range is changed -1,-1 which means it is empty

Answered By – Amir Hossein Mirzaei

Answer Checked By – Marie Seifert (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *