I was struggling implement simple search function using SearchDelegate
. I want to wait 2 second after user stop typing and then make a call request to an API.
I already check this question: How to debounce search suggestions in flutter's SearchPage Widget? and use this package https://pub.dev/packages/debounce_throttle but still not working as I expected. Every time user typing a new character, the app immediately make a call request.
This is sample code for buildResults
function
@override
Widget buildResults(BuildContext context) {
return FutureBuilder(
builder: (BuildContext context, AsyncSnapshot<List<Place>> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
itemBuilder: (context, index) => ListTile(
leading: Icon(Icons.location_city),
title: Text(snapshot.data![index].name),
onTap: () { ... do something ... },
),
itemCount: snapshot.data!.length,
);
} else {
return Center(child: CircularProgressIndicator());
}
},
future: queryChanged(query),
);
}
and Future function to make a call request
Future<List<Place>> _getLocation() async {
List<Place> displayPlaces = [];
...
...
return displayPlaces;
}
Debouncer code
final debouncer = Debouncer<String>(Duration(milliseconds: 2000), initialValue: '');
Future<List<Place>> queryChanged(String query) async {
debouncer.value = query;
return _getLocation();
}
This code works for me:
import 'package:debounce_throttle/debounce_throttle.dart';
import 'dart:async';
class AddressSearch extends SearchDelegate<Suggestion?> {
Completer<List<Suggestion>> _completer = Completer();
late final Debouncer _debouncer = Debouncer(Duration(milliseconds: 300),
initialValue: '',
onChanged: (value) {
_completer.complete(_fetchSuggestions(value)); // call the API endpoint
}
);
@override
Widget buildSuggestions(BuildContext context) {
_debouncer.value = query; // update the _debouncer
_completer = Completer(); // re-create the _completer, 'cause old one might be completed already
return FutureBuilder<List<Suggestion>>(
future: _completer.future,
builder: (context, snapshot) {
/* render your suggestions here */
if (snapshot.connectionState == ConnectionState.done) {
// If we got an error
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error} occured',
style: TextStyle(fontSize: 18),
),
);
// if we got our data
} else if (snapshot.hasData) {
// Extracting data from snapshot object
return ListView.builder(
itemBuilder: (context, index) => ListTile(
title: Text((snapshot.data?[index])!.label), // or whatever field you have in your Suggestion class
onTap: () {
close(context, snapshot.data?[index]);
},
),
itemCount: snapshot.data?.length,
);
}
}
// Displaying LoadingSpinner to indicate waiting state
return Center(
child: CircularProgressIndicator(),
);
}
);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.