通过ArrayList为阵列名称进行自定义搜索
我试图在自定义适配器中使用getFilter
方法实现搜索筛选器。通过ArrayList为阵列名称进行自定义搜索
有两种通过列表搜索的模型。
- 搜索项目的
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;
}
AFAIU你想要的歌曲相匹配的fiter如果任何这些2个条件:
歌曲的标题与全启动搜索文本
该歌曲的类型包含由
,
(逗号)分隔的部分搜索文本
如果是这样,请尝试以下搜索逻辑:
@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;
。这是同时从两个for
循环中分离出来的Java语法。这里的想法是,如果我们找到了匹配的constraint
和歌曲之间的一些流派,我们的歌曲添加到filteredList
,不想再次添加它,如果有更多的匹配类型。
P.S.如果通过很多搜索类型过滤成为性能问题,则可以考虑建立单一的正则表达式匹配一次或实施Aho–Corasick algorithm
您可以通过拆分,
String[] searmTearmArray= serachTerm.split(",");
现在使用for
循环中,您可以搜索这些词语搜索词。
我试过了,这不起作用。 –
什么是错误 –
没有错误,但是当我在像'小提琴序列式风格,light'则给出了在流派这个序列的结果,它不会给有'小提琴,电的项目, light'。 –
请通过拆分约束字符串,如以下尝试:
@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;
}
这不起作用,对于第一个关键字来说很好,但是在插入'后,'列表返回空 –
请尝试编辑答案并让我知道它是否有效。 –
一样的,但是这一次分裂后,名单将保持与第一次使用关键字找到的项目,没有任何功能的任何其他输入 –
@DastakWall你想要可科特林回答所有的搜索字词? –