0

I have my adapter that extend a class MatchableArrayAdapter that i've found on the internet.

The class allows me to have a complex layout for my list view (layout that is not only Textview, but several layout and textViews).

I have this complex layout because I'm using object with several data inside it (so I can on the same item display a name, an ID...)

So i'm passing an ArrayList of object from my fragment to my adapter.

What I want is this :

I want to add a searchView that will filter on any of the object properties (filter on ID, name, location...)

Any idea how to do that ? I've found that I need to use Filterable but I don't understand why...

user
  • 86,916
  • 18
  • 197
  • 190
Projet Sin
  • 337
  • 8
  • 20
  • Possible duplicate of [SearchView In ListView having a custom Adapter](https://stackoverflow.com/questions/23422072/searchview-in-listview-having-a-custom-adapter) – user Jan 25 '19 at 10:18

1 Answers1

0

so.. it's easier to do the filtering manually with an EditText.

but! if you still want to do it with a Filter and a SearchView, it goes like this:

  1. you need to extend the Filter class, something like this:

    private class MyFilter extends Filter {
    
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            final FilterResults results = new FilterResults();
    
            if (constraint == null || constraint.length() == 0) {
                final ArrayList<MyObject> list;
                synchronized (adapter) {
                    list = new ArrayList<>(allObjects);
                }
                results.values = list;
                results.count = list.size();
            } else {
                final String prefixString = constraint.toString().toLowerCase();
    
                final ArrayList<MyObject> values;
                synchronized (adapter) {
                    values = new ArrayList<>(allObjects);
                }
    
                final int count = values.size();
                final ArrayList<MyObject> newValues = new ArrayList<>();
    
                for (int i = 0; i < count; i++) {
                    final MyObject value = values.get(i);
                    final String valueText = value.firstName.toLowerCase() + " " + value.lastName.toLowerCase();
                    Log.i("search", valueText);
                    if (valueText.contains(prefixString)) {
                        newValues.add(value);
                        Log.i("search", "in");
                    }
                }
                results.values = newValues;
                results.count = newValues.size();
            }
            return results;
        }
    
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            adapter.students = (List<MyObject>) results.values;
            if (results.count > 0) {
                adapter.notifyDataSetChanged();
            } else {
                adapter.notifyDataSetInvalidated();
            }
        }
    }
    

notice i used firstname and lastname as fields of MyObject, and you should change that to the values you're searching for.

  1. you need to override the method getFilter in your adapter:

    @Override
    public Filter getFilter(){
        return new MyFilter();
    }
    
  2. setup the searchView query listener:

    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            adapter.getFilter().filter(query);
            return false;
        }
    
        @Override
        public boolean onQueryTextChange(String query) {
            adapter.getFilter().filter(query);
            return false;
        }
    });
    

hope that helps someone,

cheers

eiran
  • 1,378
  • 15
  • 16