Flutter 多串颤振搜索

Flutter 多串颤振搜索,flutter,Flutter,我有一个搜索字段可以过滤我的列表,它工作正常我只想对它做一些小的更改: 逻辑 当用户清除搜索字段时返回完整列表 搜索也包括在listile->subtitle中,当前仅在title 代码为便于理解,对搜索功能进行了注释 List<World> locations = [...] Widget build(BuildContext context) { return Scaffold( body: Column( children:

我有一个搜索字段可以过滤我的列表,它工作正常我只想对它做一些小的更改:

逻辑

  • 当用户清除搜索字段时返回完整列表
  • 搜索也包括在
    listile->subtitle
    中,当前仅在
    title
  • 代码为便于理解,对搜索功能进行了注释

    List<World> locations = [...]
    
    
    Widget build(BuildContext context) {
        return Scaffold(
            body: Column(
                children: [
                    buildSearch(),
                    Expanded(
                        child: ListView.builder(
                            itemCount: locations.length,
                            itemBuilder: (context, index) {
                                return Card(
                                    child: ListTile(
                                        onTap: () {},
                                        title: Text(locations[index].location),
                                        subtitle: Text(locations[index].country),
                                    ),
                                ),
                            },
                        ),
                    ),
                ],
            ),
        ),
    }
    
    Widget buildSearch() => SearchWidget(
        text: query,
        hintText: 'Search for location',
        onChanged: searchLocation,
    );
    
    void searchLocation(String query) async {
        // currently only search in titles (need to add subtitle as well)
        final newLocations = locations.where((location) {
            final nameLower = location.location.toLowerCase();
            final searchLower = query.toLowerCase();
            return nameLower.contains(searchLower);
        }).toList();
    
        // when user clear search or remove letters list wont back to it's default
        setState(() {
            this.query = query;
            this.locations = newLocations;
        });
    }
    
    更新2 我已经成功地修复了逻辑中的#2,并通过以下代码获得包含搜索结果的字幕(明确的搜索问题仍然存在)

    注意:

    我已经接受了Yair Chen的回答,但我需要做一些澄清来解决这个问题:

    基于
    Yair Chen
    的回答,我必须创建新的列表
    list filteredLocations=[]

    然后在我的
    ListView.builder
    中,我更改了
    itemCount
    child
    ,如下所示:

    ListView.builder(
      itemCount: filteredLocations.isNotEmpty ? filteredLocations.length : locations.length,
      //...
      child: filteredLocations.isNotEmpty ? card(... //filteredLocations[index].location//...) : Card(... //locations[index].location// ...),
    

    这样就解决了筛选结果上的索引问题,卡数据将获得有关其返回的列表的数据。

    您可以添加另一个名为filteredLocations的列表,然后将新列表保存到筛选位置。函数.where()也会更改您不需要的原始列表。您可以浅层复制(使用扩展运算符)列表,然后创建与查询匹配的新列表,如下所示:

    void searchLocation(String query) async {
        // currently only search in titles (need to add subtitle as well)
        // [...locations] copies the list to not change original list
        final newLocations = [...locations].where((location) {
            final nameLower = location.location.toLowerCase();
            final searchLower = query.toLowerCase();
    
            // Also adding subtitle check (whether the name contains it or the subtitle does
            return nameLower.contains(searchLower) || location.subtitle.toLowerCase().contains(searchLower);
        }).toList();
    
        // when user clear search or remove letters list wont back to it's default
        setState(() {
            this.query = query;
            this.filteredLocations = newLocations;
        });
    }
    
    这样,原始列表将永远不会更改,只更新filteredList。它还将解决当字符串为空时希望显示所有项目的问题


    祝你好运,如果你还需要什么,请告诉我:)

    嗨,你的意思是我做了一个这样的列表
    list filteredLocations=[]然后如何在视图中获取此列表项?正如您在my
    ListView.builder中看到的那样(
    我使用的是
    位置
    列表。因此,在ListView.builder中使用filteredLocations,然后您将只看到回答查询的位置。每次您在搜索功能中使用setState时,它都会以正确的位置再次呈现。|要么我不明白您的意思,要么您离题了!如果我使用
    filteredLocations
    ListView.builder
    第一次加载中,当用户打开页面时,我的列表将为空,因为在第一次加载中没有查询。(也许您可以更新您的答案?)我找到了解决方案。谢谢,我还为我的问题添加了
    注释
    部分以完成您的回答
    ListView.builder(
      itemCount: filteredLocations.isNotEmpty ? filteredLocations.length : locations.length,
      //...
      child: filteredLocations.isNotEmpty ? card(... //filteredLocations[index].location//...) : Card(... //locations[index].location// ...),
    
    void searchLocation(String query) async {
        // currently only search in titles (need to add subtitle as well)
        // [...locations] copies the list to not change original list
        final newLocations = [...locations].where((location) {
            final nameLower = location.location.toLowerCase();
            final searchLower = query.toLowerCase();
    
            // Also adding subtitle check (whether the name contains it or the subtitle does
            return nameLower.contains(searchLower) || location.subtitle.toLowerCase().contains(searchLower);
        }).toList();
    
        // when user clear search or remove letters list wont back to it's default
        setState(() {
            this.query = query;
            this.filteredLocations = newLocations;
        });
    }