Android recyclerview adapter getfilter

Filter in RecyclerView Android

Search & Load recycler view from a public API.

🚀 Hello, In this article, we are going to implement a complete page with a search view, recycler view. From fetching data to recycler view with a list of responses from the public URL “ https://picsum.photos/v2/list”. The response from API looks like.

You can find the source of this project, Made with love Kotlin & Hilt Injection

iamnaran/search-recycler-view

This project helps you to understand Hilt Integration in Android (Kotlin) It includes Retrofit Coroutines Architecture…

Ok, let’s get started with adding base URL to our Gradle implementation.

Here, In the project, the Photos model is used to populate the recycler view which is created from our API response “ https://picsum.photos/v2/list”.

Then, Let’s create an adapter for our recycler view.

And Remember the following, photosList is a list of data & photosListFiltered is a result of the list we get after filtering.

To implement search in our recyclerview. We need to implement Filterable in your adapter and override getFilter(): Filter object .

Let’s add PhotosAdapter into our PhotosActivity.We also need to implement SearchView. OnQueryTextListener in our activity/fragment .

Here, we observe results from the server and post a value to onResponse, above in activity we observe this response.

Источник

Как фильтровать RecyclerView с помощью SearchView

Я пытаюсь реализовать SearchView из библиотеки поддержки. Я хочу, чтобы пользователь использовал SearchView для фильтрации a List из фильма RecyclerView .

я последовал за несколько учебников до сих пор и я добавил SearchView до ActionBar , но я не совсем уверен, куда идти отсюда. Я видел несколько примеров, но ни один из них не показывает результатов, когда вы начинаете печатать.

это мой MainActivity :

и это мой Adapter :

7 ответов:

введение

поскольку не совсем ясно, с чем именно у вас возникли проблемы, я написал это краткое пошаговое руководство о том, как реализовать эту функцию, если у вас все еще есть вопросы, не стесняйтесь спрашивать.

у меня есть рабочий пример всего, о чем я говорю здесь в этом Репозиторий GitHub.
Если вы хотите узнать больше о пример проекта посетите Домашняя страница проекта.

в любом случае результат должен выглядеть примерно так:

если вы сначала хотите поиграть с демо-приложением, вы можете установить его из Play Store:

в любом случае, давайте начнем.

настройка SearchView

в папке res/menu создать новый файл называется main_menu.xml . В нем добавьте элемент и установите actionViewClass до android.support.v7.widget.SearchView . Поскольку вы используете библиотеку поддержки, вы должны использовать пространство имен библиотеки поддержки, чтобы установить . Ваш XML-файл должен выглядеть примерно так:

в своем Fragment или Activity вы должны раздуть это меню xml, как обычно, то вы можете искать MenuItem , которая содержит SearchView и реализовать OnQueryTextListener , который мы будем использовать для отслеживания изменений в введенный текст в SearchView :

и теперь SearchView готов к использованию. Мы реализуем логику фильтра позже в onQueryTextChange() как только мы закончим реализацию Adapter .

настройка Adapter

в первую очередь это класс модели, который я собираюсь использовать для этого примера:

это просто ваша базовая модель, которая будет отображать текст в RecyclerView . Это макет I собираюсь использовать для отображения текста:

как вы можете видеть, я использую привязку данных. Если вы никогда раньше не работали с привязкой данных, не расстраивайтесь! Это очень простой и мощный, однако я не могу объяснить, как это работает в рамках этого ответа.

это ViewHolder на ExampleModel класс:

опять ничего особенного. Он просто использует привязку данных для привязки класса модели к этому макету, как мы определили в xml-файле макета выше.

Читайте также:  Андроид смартфон как пульт телевизор

теперь мы можем, наконец, перейти к действительно интересной части: написание адаптера. Я собираюсь пропустить основную реализацию Adapter и вместо этого я собираюсь сосредоточиться на частях, которые имеют отношение к этому ответу.

но Сначала мы должны поговорить об одном: SortedList класса.

SortedList

The SortedList — это совершенно удивительный инструмент который является частью RecyclerView библиотека. Он заботится о уведомлении Adapter об изменениях в наборе данных и делает это очень эффективным способом. Единственное, что вам нужно сделать, это указать порядок элементов. Вам нужно сделать это, реализовав compare() метод, который сравнивает два элемента в SortedList как Comparator . Но вместо сортировки List используется для сортировки элементов в RecyclerView !

The SortedList взаимодействует с Adapter через Callback класс, который вы должны реализовать:

в методах в верхней части обратного вызова, как onMoved , onInserted и т. д. вы должны вызвать эквивалентный метод notify вашего Adapter . Три метода внизу compare , areContentsTheSame и areItemsTheSame вы должны реализовать в соответствии с тем, какие объекты вы хотите отобразить и в каком порядке эти объекты должны появиться на экране.

давайте рассмотрим эти методы по один:

это compare() метод, о котором я говорил ранее. В этом примере я просто передаю вызов Comparator , который сравнивает две модели. Если вы хотите, чтобы элементы отображались в алфавитном порядке на экране. Этот компаратор может выглядеть так:

теперь давайте посмотрим на следующий метод:

цель этого метода-определить, изменилось ли содержимое модели. Элемент SortedList использует это, чтобы определите, нужно ли вызывать событие изменения — другими словами, если RecyclerView должен пересекать старую и новую версию. Если вы моделируете классы имеют правильный equals() и hashCode() реализация вы обычно можете просто реализовать его, как показано выше. Если мы добавим equals() и hashCode() реализации ExampleModel класс это должно выглядеть примерно так:

быстрая сторона Примечание: большинство IDE, как Android Studio, IntelliJ и Eclipse имеют функциональность для создания equals() и hashCode() реализации для вас одним нажатием кнопки! Так что вам не придется реализовывать их самостоятельно. Посмотрите в интернете, как это работает в вашей среде IDE!

теперь давайте посмотрим на последний метод:

The SortedList использует этот метод, чтобы проверить, если два элемента относятся к одной и той же вещи. В самых простых выражениях (не объясняя, как SortedList работает) это используется, чтобы определить, если объект уже содержится в List и если добавить, перемещение или изменение анимации должны быть воспроизведены. Если ваши модели имеют идентификатор, вы обычно сравниваете только идентификатор в этом методе. Если они этого не делают, вам нужно выяснить какой-то другой способ проверить это, но в конечном итоге вы реализуете это зависит от вашего конкретного приложения. Как правило, это самый простой вариант, чтобы дать всем моделям идентификатор — это может быть, например, поле первичного ключа, если вы запрашиваете данные из базы данных.

с SortedList.Callback правильно реализовано мы можем создать экземпляр SortedList :

как первый параметр в конструкторе SortedList вам нужно пройти класс ваших моделей. Другой параметр-это просто SortedList.Callback мы определили выше.

теперь давайте перейдем к делу: если мы реализуем Adapter С SortedList это должно выглядеть примерно так:

The Comparator используется для сортировки элемента передается через конструктор, так что мы можем использовать тот же Adapter даже если элементы должны отображаться в другом порядке.

теперь мы почти закончили! Но Сначала нам нужен способ добавить или удалить элементы в Adapter . Для этого мы можем добавить методы к Adapter , которые позволяют добавлять и удалять элементы SortedList :

нам не нужно вызывать какие-либо методы уведомления здесь, потому что SortedList уже делает это через SortedList.Callback ! Кроме того, реализация этих методов довольно прямо вперед, с одним исключением: метод remove, который удаляет List моделей. Так как SortedList имеет только один метод удаления, который может удалить один объект, который нам нужно перебрать по списку и удалить модели по одному. Звоню beginBatchedUpdates() в начале партии все изменения, которые мы собираемся сделать на SortedList вместе и повышает производительность. Когда мы зовем endBatchedUpdates() the RecyclerView уведомления обо всех изменениях сразу.

Читайте также:  Корейский язык для андроида

кроме того, что у вас есть нужно понять, что если вы добавляете объект в SortedList и это уже в SortedList он не будет заново добавлен. Вместо этого SortedList использует areContentsTheSame() метод, чтобы выяснить, если объект изменился — и если он имеет элемент в RecyclerView будет обновляться.

в любом случае, я обычно предпочитаю один метод, который позволяет мне заменить все элементы в RecyclerView сразу. Удалите все, что не находится в List и добавить все элементы, которые отсутствуют в SortedList :

этот метод снова пакеты обновлений для повышения производительности. Первый цикл находится в обратном порядке, так как удаление элемента в начале испортило бы индексы всех элементов, которые появляются после него, и это может привести в некоторых случаях к таким проблемам, как несогласованность данных. После этого мы просто добавляем List до SortedList используя addAll() чтобы добавить все элементы, которые еще не находятся в SortedList и-так же, как я описал выше-обновить все элементы которые уже находятся в SortedList но изменились.

и Adapter завершено. Все это должно выглядеть примерно так:

единственное, чего не хватает сейчас, это реализовать фильтрацию!

реализация логики фильтра

для реализации логики фильтра мы сначала должны определить List всех возможных моделей. Для этого примера я создаю List на ExampleModel случаи из массив фильмов:

ничего особенного здесь не происходит, мы просто создаем экземпляр Adapter и RecyclerView . После этого мы создаем List моделей из названий фильмов в MOVIES массив. Затем мы добавляем все модели SortedList .

теперь мы можем вернуться к onQueryTextChange() который мы определили ранее и начинаем реализовывать логику фильтра:

это снова довольно прямо вперед. Мы вызываем метод filter() и проходите в List на ExampleModel s, а также строка запроса. Затем мы вызываем replaceAll() на Adapter и пройти в фильтрованный List возвращено filter() . Мы также должны позвонить scrollToPosition(0) на RecyclerView чтобы убедиться, что пользователь всегда может видеть все элементы при поиске чего-то. В противном случае RecyclerView может оставаться в прокрученном вниз положении во время фильтрации и впоследствии скрыть несколько элементов. Прокрутка вверх обеспечивает лучший пользовательский интерфейс во время испытующий.

единственное, что осталось сделать сейчас, чтобы реализовать :

первое, что мы делаем здесь-это вызов toLowerCase() в строке запроса. Мы не хотим, чтобы наша функция поиска учитывала регистр и вызывала toLowerCase() на всех строках мы сравниваем мы можем гарантировать, что мы возвращаем те же результаты независимо от случая. Затем он просто повторяет все модели в List мы прошли в нее и проверяет, если строка запроса содержится в текст модели. Если это так, то модель добавляется к фильтруемому List .

и это все! Приведенный выше код будет работать на уровне API 7 и выше, и начиная с уровня API 11 вы получаете анимацию элементов бесплатно!

я понимаю, что это очень подробное описание, которое, вероятно, делает все это более сложным, чем на самом деле, но есть способ обобщить всю эту проблему и сделать реализацию Adapter на основе SortedList гораздо проще.

обобщение проблемы и упрощение адаптера

в этом разделе я не буду вдаваться в подробности-отчасти потому, что я сталкиваюсь с ограничением символов для ответов на переполнение стека, но также и потому, что большинство из них уже объяснено выше, но чтобы суммировать изменения: мы можем реализовать базу Adapter класс, который уже заботится о решении SortedList а также привязка моделей к ViewHolder экземпляров и обеспечивает удобный способ реализации Adapter на основе SortedList . Для этого мы должны сделать две вещи:

  • нам нужно создать ViewModel интерфейс, который все классы моделей должны реализовать
  • нам нужно создать ViewHolder подкласс, который определяет a bind() метод Adapter можно использовать для автоматической привязки моделей.
Читайте также:  2ком тв для андроид iconbit не работает

это позволяет нам просто сосредоточиться на содержании, которое должно отображаться в RecyclerView by просто реализуя модели и там соответствующие ViewHolder реализаций. Используя этот базовый класс, нам не нужно беспокоиться о сложных деталях Adapter и SortedList .

SortedListAdapter

из-за ограничения символов для ответов на StackOverflow я не могу пройти каждый шаг реализации этого базового класса или даже добавить полный исходный код здесь, но вы можете найти полный исходный код этого базового класса — я назвал его SortedListAdapter — in это GitHub Gist.

чтобы сделать вашу жизнь простой я опубликовал библиотеку на jCenter, которая содержит SortedListAdapter ! Если вы хотите использовать его, то все, что вам нужно сделать, это добавить эту зависимость для построения вашего приложения.файл gradle:

вы можете найти дополнительную информацию об этой библиотеке на главной странице библиотеки.

с помощью SortedListAdapter

использовать элемент SortedListAdapter мы должны сделать два изменения:

изменить ViewHolder так, что он простирается SortedListAdapter.ViewHolder . Параметр type должен быть моделью, которая должна быть привязана к этому ViewHolder — в данном случае ExampleModel . Вы должны привязать данные к вашим моделям в performBind() вместо bind() .

убедитесь, что все ваши модели реализации ViewModel интерфейс:

после что мы просто должны обновить ExampleAdapter направить SortedListAdapter и удалить все, что нам больше не нужно. Параметр type должен быть типом модели, с которой вы работаете-в этом случае ExampleModel . Но если вы работаете с различными типами моделей, установите параметр типа ViewModel .

после этого мы закончим! Однако последнее, что нужно отметить: SortedListAdapter не имеет то же самое add() , remove() или replaceAll() методы наши оригинальные ExampleAdapter имел. Он использует отдельный Editor объект для изменения элементов в списке, которые могут быть доступны через edit() метод. Так что если вы хотите удалить или добавить элементы, которые вы должны называть edit() затем добавить и удалить элементы на этом Editor экземпляр и как только вы закончите, позвони commit() на нем применить изменения к SortedList :

все изменения, которые вы делаете таким образом, объединяются вместе для повышения производительности. Элемент replaceAll() метод, который мы реализовали в главах выше также присутствует на этом :

если вы забыли назвать commit() тогда ни одно из ваших изменений не будет применено!

все, что вам нужно сделать, это добавить filter метод RecyclerView.Adapter :

itemsCopy инициализируется в конструкторе адаптера, как itemsCopy.addAll(items) .

если вы это сделаете, просто позвоните filter С OnQueryTextListener :

это пример фильтрации моей телефонной книги по имени и номеру телефона.

после @начала знакомства с Ченнай Kamoji в более чистый путь, мы можем просто использовать фильтрующийся, его имел в виду, что:

E вот общий тип, вы можете расширить его с помощью вашего класса:

или просто измените E на тип, который вы хотите ( например)

затем из searchView (виджет вы можете поместить в меню.xml):

просто создайте два списка в адаптере один orignal и один temp и реализует Filterable.

Я рекомендую изменить решение @Xaver Kapeller с двумя вещами ниже, чтобы избежать проблемы после того, как вы очистили искомый текст (фильтр больше не работал) из-за того, что список back of adapter имеет меньший размер, чем список фильтров, и произошло исключение IndexOutOfBoundsException. Так что код нужно изменить, как показано ниже

и изменить также в функциональности moveItem

надеюсь, что это может помочь вам!

я решил такую же проблему, используя ссылку с некоторыми изменениями в нем. фильтр поиска на RecyclerView с картами. Это вообще возможно? (надеюсь, что это помогает).

вот мой класс адаптера

в методе OnQueryTextChangeListener () используйте свой адаптер. Я бросил его на фрагмент, как мой адптер находится в фрагменте. Вы можете использовать адаптер непосредственно, если он находится в вашем классе активности.

Источник

Оцените статью