Often we use a search bar in our app to perform autocomplete-style searches via network calls. In such a case, it is not feasible to perform a network request with every character that the user types/changes; that would result in wasted network calls. it is better to search once the user pauses or stops typing. This can be achieved using a Debouncer, which uses a timer to delay the search request until it stops receiving text changes for half a second, or any duration that you set.

Add this class Debouncer, anywhere in your project.

class Debouncer {
  final int milliseconds;
  VoidCallback action;
  Timer _timer;

  Debouncer({this.milliseconds});

  run(VoidCallback action) {
    if (null != _timer) {
      _timer.cancel();
    }
    _timer = Timer(Duration(milliseconds: milliseconds), action);
  }
}

And back in the screen where we are performing the search.

Create an instance of the Debouncer class. You can modify the duration.

final _debouncer = Debouncer(milliseconds: 500);

Finally, in the search bar onChanged event, use the debouncer and perform the search action.

onChanged: (string) {
  _debouncer.run(() {
    print(string);
    //perform search here
  }
);

Example of the search bar using TextField:

Row(
  children: <Widget>[
    Icon(Icons.search),
    SizedBox(width: 8),
    Flexible(
      child: TextField(
        decoration: new InputDecoration(hintText: 'Search'),
        onChanged: (string) {
          _debouncer.run(() {
            print(string);
            //perform search here
          });
        },
      ),
    ),
  ],
)