通过ArrayList自定义搜索数组名称

时间:2017-06-05 06:45:38

标签: android search arraylist filter adapter

我尝试在自定义适配器中使用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;
}

3 个答案:

答案 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如果满足以下两个条件中的任何一个,您希望歌曲与适合者匹配:

  1. 歌曲的标题以整个搜索文字开头

  2. 该歌曲的流派包含由,(逗号)分隔的搜索文本的一部分

  3. 如果是这样,请尝试按照搜索逻辑:

            @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循环,您可以搜索这些字词。