我尝试在自定义适配器中使用getFilter
方法实现搜索过滤器。
列表中有两种搜索模式。
title
genre[]
。(但我刚刚在这里讨论genre
)。
以下代码运行正常,但我需要的是在genre[]
中搜索更加自定义的方式。
我想要达到的目标是:( 我想要的 ):
multi-keyword
搜索,每个类别用,
分隔。例如:genre1,genre2
(我做了什么) :
当我输入genre1,genre2
时,它会以流派的形式提供具有此序列的项目,但不会提供genre1,genre3,genre2
,或只提供genre1
。
请帮忙吗?
用getFilter:
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
dataList = (List<ProductLocal>) results.values;
notifyDataSetChanged();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<ProductLocal> filteredList = new ArrayList<>();
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < dataListFilter.size(); i++) {
ProductLocal dataNames = dataListFilter.get(i);
String genreStr = "";
for (String str : dataNames.getGenre()) {
genreStr += str + ",";
}
if (dataNames.getTitle().toLowerCase().startsWith(constraint.toString())
|| genreStr.toLowerCase().contains(constraint.toString())) {
filteredList.add(dataNames);
}
}
results.count = filteredList.size();
results.values = filteredList;
return results;
}
};
return filter;
}
答案 0 :(得分:1)
请尝试拆分约束字符串,如下所示:
@Override
public Filter getFilter() {
@SuppressWarnings("UnnecessaryLocalVariable")
Filter filter = new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
dataList = (List<ProductLocal>) results.values;
notifyDataSetChanged();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<ProductLocal> filteredList = new ArrayList<>();
for (int i = 0; i < dataListFilter.size(); i++) {
ProductLocal dataNames = dataListFilter.get(i);
int count = 0;
String[] terms = constraint.toString().split(",");
for (int j = 0; j < terms.length; j++) {
String term = terms[j];
for (String str : dataNames.getGenre()) {
if (str.equals(term) || str.contains(term)) {
count++;
if (count == terms.length) {
filteredList.add(dataNames);
}
}
}
}
}
results.count = filteredList.size();
results.values = filteredList;
return results;
}
};
return filter;
}
答案 1 :(得分:1)
AFAIU如果满足以下两个条件中的任何一个,您希望歌曲与适合者匹配:
歌曲的标题以整个搜索文字开头
该歌曲的流派包含由,
(逗号)分隔的搜索文本的一部分
如果是这样,请尝试按照搜索逻辑:
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults results = new FilterResults();
List<ProductLocal> filteredList = new ArrayList<>();
String searchText = constraint.toString().toLowerCase();
String[] split = searchText.split(",");
ArrayList<String> searchGenres = new ArrayList<String>(split.length);
for (int i = 0; i < split.length; i++)
{
// remove spaces
String trim = split[i].trim();
// skip empty entries
if (trim.length() > 0)
searchGenres.add(trim);
}
for (ProductLocal dataNames : dataListFilter)
{
// filter by title
if (dataNames.getTitle().toLowerCase().startsWith(searchText))
{
filteredList.add(dataNames);
}
else
{
// filter by genres
// search for at least one common genre between song and search text
outer:
for (String songGenre : dataNames.getGenre())
{
for (String searchGenre : searchGenres)
{
if (songGenre.toLowerCase().contains(searchGenre))
{
filteredList.add(dataNames);
break outer;
}
}
}
}
}
results.count = filteredList.size();
results.values = filteredList;
return results;
}
这里唯一棘手的地方是break outer;
。这是一种Java语法,可以同时从两个for
循环中突破。这里的想法是,如果我们在constraint
和一首歌曲之间找到某种类型的匹配,我们会将歌曲添加到filteredList
,如果我想再添加一首歌曲,有更多匹配的流派。
P.S。如果许多搜索类型的过滤成为性能问题,您可以考虑构建单个RegEx以同时匹配所有搜索字词或实施Aho–Corasick algorithm
答案 2 :(得分:0)
您可以按,
String[] searmTearmArray= serachTerm.split(",");
现在使用for
循环,您可以搜索这些字词。