How to debounce Textfield onChange in Dart?
Implementation
Import dependencies:
import 'dart:async';
In your widget state declare a timer:
Timer _debounce;
Add a listener method:
_onSearchChanged(String query) { if (_debounce?.isActive ?? false) _debounce.cancel(); _debounce = Timer(const Duration(milliseconds: 500), () { // do something with query }); }
Don't forget to clean up:
@overridevoid dispose() { _debounce?.cancel(); super.dispose();}
Usage
In your build tree hook the onChanged
event:
child: TextField( onChanged: _onSearchChanged, // ... )
You can make Debouncer
class using Timer
import 'package:flutter/foundation.dart';import 'dart:async';class Debouncer { final int milliseconds; VoidCallback action; Timer _timer; Debouncer({ this.milliseconds }); run(VoidCallback action) { if (_timer != null) { _timer.cancel(); } _timer = Timer(Duration(milliseconds: milliseconds), action); }}
Declare it
final _debouncer = Debouncer(milliseconds: 500);
and trigger it
onTextChange(String text) { _debouncer.run(() => print(text));}
Using BehaviorSubject from rxdart lib is a good solution.It ignores changes that happen within X seconds of the previous.
final searchOnChange = new BehaviorSubject<String>();...TextField(onChanged: _search)...void _search(String queryString) { searchOnChange.add(queryString);} void initState() { searchOnChange.debounceTime(Duration(seconds: 1)).listen((queryString) { >> request data from your API });}