Flutter - 将未来列表传递给 SearchDelegate

Flutter - Pass a Future List to a SearchDelegate

我一直在关注 - boring flutter show 上的 Flutter 搜索教程 .我一直在尝试使用从未来列表派生的列表来实现相同的功能,其中数据来自 api(在本例中为 Aqueduct 服务器)。

目前我的屏幕列出了 api 中的所有联系人,我现在想搜索该联系人列表。我假设最好的做法是将相同的列表(已经显示)传递给搜索委托。不幸的是,我不确定如何实现这一目标。

我的代码如下(请注意我已经删除了这个例子的一些代码):

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();
  }
}

所以简而言之,我需要通过 'ContactSearch()' 传递正确的 list/data:

showSearch(
  context: context,
  delegate: ContactSearch(),
);

提前致谢。

基本上,您必须将 FutureBuilder 进一步向上移动到小部件层次结构中,因此搜索框和正文都在其下方。然后,您只需将数据推送到 ContactSearch。

例如:

@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. */),
          ),
        );
      }
  );
}