Search code examples
androidlistviewfiltersearchviewandroid-search

Search filter in listview for array of strings with android SearchView


I need to filter my list items via getFilter method, In my Model class, I have an array variable named genre.

This genre sometimes is one word, and sometimes more than one separated with , . For example like:

android, iPhone, blackberry.

Now in my code when I try to search in my list for an item, it will only search for the first word(android). In another word, if I try to search for iPhone, this item will not be shown in my new filtered list.

In below code I know I'm doing it wrong, but can you help me correct it, please?

@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;
                }
                genreStr = genreStr.length() > 0 ? genreStr.substring(0,genreStr.length() - 2) : genreStr;
                if (genreStr.toLowerCase().startsWith(constraint.toString()) ) {
                    filteredList.add(dataNames);
                }
            }
            results.count = filteredList.size();
            results.values = filteredList;
            return results;
        }
    };
    return filter;
}

And my another question is:

How can I search for items with more than one genre seperatted with , ?

For example query = android,blackberry

And result comes up with all items that have this two genres


Solution

  • For comparing the strings partially you can use the indexOf function like below.

    if(dataNames.getGenre().toLowerCase().indexOf(constraint)>-1){
     //add to your list
     filteredList.add(dataNames);
    } else{
      //doesn't satisfy the filter condition. 
    }
    

    Another thing noticed is that if your getGenre() is a List you don't need to add all the string together and check the filter condition you can do it like below. You can split the comma separated value to a list string and loop through it and check filter.

    List<String> filterList = Arrays.asList(constraint.split(","))
    bool hasAdded;
    for (String str : dataNames.getGenre()) 
    {
      for (String filter : filterList) {
        if(str.toLowerCase().indexOf(filter.trim().toLowerCase())>-1){
        //add to your list
        filteredList.add(dataNames);
        hasAdded = true;
        break;
       }
       if(hasAdded) break;
      }
    }
    

    Also you can change the for loop with foreach for looping dataListFilter.