问题
I've been following a Flutter Search tutorial on the - boring flutter show . I have been trying to implement the same functionality using a list which is derived from a Future List where the data comes from an api (in this case and Aqueduct server).
Currently my screen lists all the contacts from the api, i'd now like to search against that contacts list. I'm assuming it would be best practice to pass the same list (which is already being displayed) to the search delegate. Unfortunately i'm not sure how to achieve this.
My code is as follows (please note i've stripped down some of the code for this examples):
class _ContactsScreenState extends State<ContactsScreen> {
static const _usersUrl = //url info;
static final _token = //token info;
static final _headers = {
"Content-type" : "application/json",
"Accept": "application/json",
"Authorization": "Bearer $_token",
};
HttpRequestStatus httpRequestStatus = HttpRequestStatus.NOT_DONE;
Future<List<Contact>> readContacts() async {
final response = await http.get(_usersUrl, headers: _headers);
List responseJson = json.decode(response.body.toString());
List<Contact> contactList = createContactList(responseJson);
return contactList;
}
List<Contact> createContactList(List data) {
List<Contact> list = List();
for (int i = 0; i < data.length; i++) {
String name = data[i]["name"];
int id = data[i]["id"];
Contact user = Contact(name: name, id: id);
list.add(user);
}
return list;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('List Contacts'),
actions: [
IconButton(
icon: Icon(Icons.search),
tooltip: 'Search',
onPressed: (){
showSearch(
context: context,
delegate: ContactSearch(),
);
}
),
],
),
body: Container(
child: FutureBuilder<List<Contact>>(
future: readContacts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
//Code which displays the data (works fine);
}
}
),
)
)
}
}
class ContactSearch extends SearchDelegate<Contact> {
@override
<Widget> buildActions(BuildContext context){
//
}
@override
Widget buildLeading(BuildContext context){
//
}
@override
Widget buildSuggestions(BuildContext context){
//Pass contacts list to here and compares agains 'query'
}
@override
Widget buildResults(BuildContext context) {
return container();
}
}
So in brief, i need to pass the correct list/data through 'ContactSearch()':
showSearch(
context: context,
delegate: ContactSearch(),
);
Thanks in advance.
回答1:
Basically you have to move the FutureBuilder further up the widget hierarchy, so both the search box as well as the body are below it. Then you can simply push your data into the ContactSearch.
For Example:
@override
Widget build(BuildContext context) {
return FutureBuilder<List<Contact>>(
future: readContacts(),
builder: (context, snapshot) {
return Scaffold(
appBar: AppBar(
title: Text('List Contacts'),
actions: [
IconButton(
icon: Icon(Icons.search),
tooltip: 'Search',
onPressed: !snapshot.hasData ? null : () {
showSearch(
context: context,
delegate: ContactSearch(snapshot.data),
);
}
),
],
),
body: Container(
child:
(snapshot.hasData ?
//Code which displays the data (works fine);
: /* show errors/progress/etc. */),
),
);
}
);
}
来源:https://stackoverflow.com/questions/54482450/flutter-pass-a-future-list-to-a-searchdelegate