SearchView, который фильтрует сложные данные (объект и пользовательский макет) - PullRequest
0 голосов
/ 23 января 2019

У меня есть адаптер, который расширяет класс MatchableArrayAdapter , который я нашел в Интернете.

Этот класс позволяет мне иметь сложный макет для представления списка (макет, которыйне только Textview, но несколько макетов и textViews.

У меня сложный макет, потому что я использую объект с несколькими данными внутри него (поэтому я могу на одном и том же элементе отображать имя, идентификатор ...)

Итак, я передаю ArrayList объекта из моего фрагмента в мой адаптер.

То, что я хочу, это:

Я хочу добавить searchView , который будет фильтр на любой объект свойства (фильтрна ID, имя, место ...)

Есть идеи, как это сделать?Я обнаружил, что мне нужно использовать Filterable , но я не понимаю, почему ...

1 Ответ

0 голосов
/ 17 июня 2019

так что ... проще выполнить фильтрацию вручную с помощью EditText.

но! если вы все еще хотите сделать это с помощью Filter и SearchView, это выглядит так:

  1. вам нужно расширить класс Filter, примерно так:

    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();
            }
        }
    }
    

обратите внимание, что я использовал имя и фамилию в качестве полей MyObject, и вы должны изменить это значение на искомые значения.

  1. вам нужно переопределить метод getFilter в вашем адаптере:

    @Override
    public Filter getFilter(){
        return new MyFilter();
    }
    
  2. настройка прослушивателя запроса searchView:

    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;
        }
    });
    

надеюсь, что это кому-то поможет,

ура

...