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=[]代码>然后如何在视图中获取此列表项?正如您在myListView.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;
});
}