Wisozk Holo 🚀

How to filter a RecyclerView with a SearchView

February 16, 2025

How to filter a RecyclerView with a SearchView

Filtering a RecyclerView with a SearchView is a communal and indispensable project successful Android improvement. It offers a person-affable manner to dynamically show applicable information based mostly connected person enter. This almighty operation permits for a seamless and interactive person education, important for contemporary app improvement. Mastering this method is a cardinal accomplishment for immoderate Android developer trying to make businesslike and participating purposes.

Mounting ahead the RecyclerView and Adapter

Archetypal, guarantee your RecyclerView and Adapter are accurately fit ahead. This includes creating the RecyclerView format, defining the ViewHolder, and implementing the adapter logic to hindrance your information. Your information origin, which volition beryllium filtered, ought to beryllium easy accessible inside your adapter. This setup kinds the instauration for implementing the hunt performance.

See utilizing a Database to clasp your first information and a abstracted Database to clasp the filtered information. This separation permits you to manipulate the displayed information with out affecting the first information fit. This attack ensures information integrity and simplifies the filtering procedure.

Implementing the SearchView

The SearchView widget supplies the person interface for coming into hunt queries. You tin adhd it to your format straight oregon embed it inside the app barroom. Erstwhile added, you demand to instrumentality an OnQueryTextListener to perceive for matter adjustments successful the SearchView. This listener offers 2 cardinal strategies: onQueryTextSubmit and onQueryTextChange.

For existent-clip filtering, onQueryTextChange is important. It’s known as all clip the person modifies the hunt matter. This permits for contiguous suggestions and dynamic updating of the RecyclerView. Piece onQueryTextSubmit is sometimes utilized for initiating searches last the person presses “Participate”, utilizing onQueryTextChange presents a much responsive education.

Creating the Filter Logic

Inside the onQueryTextChange technique, you instrumentality the existent filtering logic. This includes iterating done your first information fit and evaluating all point towards the hunt question. The examination tin beryllium lawsuit-insensitive to better person education.

A communal attack is to usage a elemental drawstring examination to cheque if the hunt question is a substring of a peculiar information tract inside your objects. You tin usage Java’s accommodates() technique oregon daily expressions for much analyzable matching. Last filtering, replace the filtered information database and notify the adapter that the information fit has modified. This triggers the RecyclerView to refresh its show, exhibiting lone the filtered objects.

  1. Acquire the hunt question from the SearchView.
  2. Loop done your first information fit.
  3. Cheque if the actual point matches the question.
  4. Adhd matching objects to the filtered database.
  5. Replace the adapter’s information with the filtered database.
  6. Call adapter.notifyDataSetChanged() to refresh the RecyclerView.

Optimizing for Show

For bigger datasets, filtering all point connected all matter alteration tin contact show. Optimizations similar utilizing a inheritance thread for filtering and implementing much businesslike hunt algorithms tin importantly better the person education. Libraries similar RxJava tin beryllium utile for dealing with inheritance duties and simplifying asynchronous operations.

See utilizing a much businesslike filtering mechanics than elemental drawstring matching. Methods similar indexing oregon pre-processing your information tin drastically trim the filtering clip. For illustration, creating a Trie information construction tin optimize substring searches. Research alternate approaches to discovery the champion acceptable for your information and show necessities. Seat this article for enhancing your app show: Show Suggestions.

Infographic Placeholder: Illustrating the filtering procedure travel.

  • Usage a inheritance thread for filtering ample datasets.
  • Instrumentality businesslike hunt algorithms for analyzable matching.

Illustration utilizing Filterable

Implementing the Filterable interface successful your adapter offers a structured manner to grip filtering. This interface requires implementing the getFilter() methodology, which returns a Filter entity. Wrong the Filter entity’s performFiltering() technique, you instrumentality the existent filtering logic.

Illustration: Filtering a database of names

Fto’s opportunity your RecyclerView shows a database of names. Once the person sorts “Jo” into the SearchView, the database dynamically updates to entertainment lone names containing “Jo”, similar “John” and “Joseph”. This supplies a responsive and intuitive hunt education.

  • Guarantee your information is easy accessible.
  • Replace your adapter to indicate information modifications.

In accordance to a Stack Overflow study, RecyclerView is the about fashionable manner to show lists successful Android apps. Businesslike filtering is important for a affirmative person education.

Often Requested Questions

Q: However tin I better the show of RecyclerView filtering?

A: Usage inheritance threads, businesslike hunt algorithms, and see libraries similar RxJava.

Filtering RecyclerViews with SearchViews is a cardinal accomplishment successful Android improvement. By pursuing these champion practices, you tin make a creaseless, businesslike, and partaking person education. Retrieve to optimize for show, particularly once dealing with ample datasets. See exploring precocious filtering methods and leveraging libraries to heighten your implementation additional. Cheque retired these sources for much accusation: Android Hunt Dialog, RecyclerView Documentation, and RecyclerView Tutorial.

Question & Answer :
I americium making an attempt to instrumentality the SearchView from the activity room. I privation the person to beryllium to usage the SearchView to filter a Database of motion pictures successful a RecyclerView.

I person adopted a fewer tutorials truthful cold and I person added the SearchView to the ActionBar, however I americium not truly certain wherever to spell from present. I person seen a fewer examples however no of them entertainment outcomes arsenic you commencement typing.

This is my MainActivity:

national people MainActivity extends ActionBarActivity { RecyclerView mRecyclerView; RecyclerView.LayoutManager mLayoutManager; RecyclerView.Adapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { ace.onCreate(savedInstanceState); setContentView(R.structure.activity_recycler_view); mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); mRecyclerView.setHasFixedSize(actual); mLayoutManager = fresh LinearLayoutManager(this); mRecyclerView.setLayoutManager(mLayoutManager); mAdapter = fresh CardAdapter() { @Override national Filter getFilter() { instrument null; } }; mRecyclerView.setAdapter(mAdapter); } @Override national boolean onCreateOptionsMenu(Card card) { // Inflate the card; this provides gadgets to the act barroom if it is immediate. getMenuInflater().inflate(R.card.menu_main, card); SearchManager searchManager = (SearchManager) getSystemService(Discourse.SEARCH_SERVICE); SearchView searchView = (SearchView) card.findItem(R.id.menu_search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); instrument actual; } @Override national boolean onOptionsItemSelected(MenuItem point) { // Grip act barroom point clicks present. The act barroom volition // mechanically grip clicks connected the Location/Ahead fastener, truthful agelong // arsenic you specify a genitor act successful AndroidManifest.xml. int id = point.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { instrument actual; } instrument ace.onOptionsItemSelected(point); } } 

And this is my Adapter:

national summary people CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> implements Filterable { Database<Film> mItems; national CardAdapter() { ace(); mItems = fresh ArrayList<Film>(); Film film = fresh Film(); film.setName("Spiderman"); film.setRating("ninety two"); mItems.adhd(film); film = fresh Film(); film.setName("Doom three"); film.setRating("ninety one"); mItems.adhd(film); film = fresh Film(); film.setName("Transformers"); film.setRating("88"); mItems.adhd(film); film = fresh Film(); film.setName("Transformers 2"); film.setRating("87"); mItems.adhd(film); film = fresh Film(); film.setName("Transformers three"); film.setRating("86"); mItems.adhd(film); film = fresh Film(); film.setName("Noah"); film.setRating("86"); mItems.adhd(film); film = fresh Film(); film.setName("Ironman"); film.setRating("86"); mItems.adhd(film); film = fresh Film(); film.setName("Ironman 2"); film.setRating("86"); mItems.adhd(film); film = fresh Film(); film.setName("Ironman three"); film.setRating("86"); mItems.adhd(film); } @Override national ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { Position v = LayoutInflater.from(viewGroup.getContext()).inflate(R.structure.recycler_view_card_item, viewGroup, mendacious); instrument fresh ViewHolder(v); } @Override national void onBindViewHolder(ViewHolder viewHolder, int i) { Film film = mItems.acquire(i); viewHolder.tvMovie.setText(film.getName()); viewHolder.tvMovieRating.setText(film.getRating()); } @Override national int getItemCount() { instrument mItems.measurement(); } people ViewHolder extends RecyclerView.ViewHolder{ national TextView tvMovie; national TextView tvMovieRating; national ViewHolder(Position itemView) { ace(itemView); tvMovie = (TextView)itemView.findViewById(R.id.movieName); tvMovieRating = (TextView)itemView.findViewById(R.id.movieRating); } } } 

Instauration

Since it is not truly broad from your motion what precisely you are having problem with, I wrote ahead this speedy walkthrough astir however to instrumentality this characteristic; if you inactive person questions awareness escaped to inquire.

I person a running illustration of all the things I americium speaking astir present successful this GitHub Repository.

Successful immoderate lawsuit the consequence ought to appears to be like thing similar this:

demo image

If you archetypal privation to drama about with the demo app you tin instal it from the Drama Shop:

Get it on Google Play

Anyhow lets acquire began.


Mounting ahead the SearchView

Successful the folder res/card make a fresh record known as main_menu.xml. Successful it adhd an point and fit the actionViewClass to android.activity.v7.widget.SearchView. Since you are utilizing the activity room you person to usage the namespace of the activity room to fit the actionViewClass property. Your xml record ought to expression thing similar this:

<card xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-car"> <point android:id="@+id/action_search" android:rubric="@drawstring/action_search" app:actionViewClass="android.activity.v7.widget.SearchView" app:showAsAction="ever"/> </card> 

Successful your Fragment oregon Act you person to inflate this card xml similar accustomed, past you tin expression for the MenuItem which comprises the SearchView and instrumentality the OnQueryTextListener which we are going to usage to perceive for adjustments to the matter entered into the SearchView:

@Override national boolean onCreateOptionsMenu(Card card) { getMenuInflater().inflate(R.card.menu_main, card); last MenuItem searchItem = card.findItem(R.id.action_search); last SearchView searchView = (SearchView) searchItem.getActionView(); searchView.setOnQueryTextListener(this); instrument actual; } @Override national boolean onQueryTextChange(Drawstring question) { // Present is wherever we are going to instrumentality the filter logic instrument mendacious; } @Override national boolean onQueryTextSubmit(Drawstring question) { instrument mendacious; } 

And present the SearchView is fit to beryllium utilized. We volition instrumentality the filter logic future connected successful onQueryTextChange() erstwhile we are completed implementing the Adapter.


Mounting ahead the Adapter

Archetypal and foremost this is the exemplary people I americium going to usage for this illustration:

national people ExampleModel { backstage last agelong mId; backstage last Drawstring mText; national ExampleModel(agelong id, Drawstring matter) { mId = id; mText = matter; } national agelong getId() { instrument mId; } national Drawstring getText() { instrument mText; } } 

It’s conscionable your basal exemplary which volition show a matter successful the RecyclerView. This is the format I americium going to usage to show the matter:

<?xml interpretation="1.zero" encoding="utf-eight"?> <format xmlns:android="http://schemas.android.com/apk/res/android"> <information> <adaptable sanction="exemplary" kind="com.github.wrdlbrnft.searchablerecyclerviewdemo.ui.fashions.ExampleModel"/> </information> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:inheritance="?attr/selectableItemBackground" android:clickable="actual"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="8dp" android:matter="@{exemplary.matter}"/> </FrameLayout> </format> 

Arsenic you tin seat I usage Information Binding. If you person ne\’er labored with information binding earlier don’t beryllium discouraged! It’s precise elemental and almighty, nevertheless I tin’t explicate however it plant successful the range of this reply.

This is the ViewHolder for the ExampleModel people:

national people ExampleViewHolder extends RecyclerView.ViewHolder { backstage last ItemExampleBinding mBinding; national ExampleViewHolder(ItemExampleBinding binding) { ace(binding.getRoot()); mBinding = binding; } national void hindrance(ExampleModel point) { mBinding.setModel(point); } } 

Once more thing particular. It conscionable makes use of information binding to hindrance the exemplary people to this structure arsenic we person outlined successful the format xml supra.

Present we tin eventually travel to the truly absorbing portion: Penning the Adapter. I americium going to skip complete the basal implementation of the Adapter and americium alternatively going to ore connected the elements which are applicable for this reply.

However archetypal location is 1 happening we person to conversation astir: The SortedList people.


SortedList

The SortedList is a wholly astonishing implement which is portion of the RecyclerView room. It takes attention of notifying the Adapter astir modifications to the information fit and does truthful it a precise businesslike manner. The lone happening it requires you to bash is specify an command of the parts. You demand to bash that by implementing a comparison() technique which compares 2 components successful the SortedList conscionable similar a Comparator. However alternatively of sorting a Database it is utilized to kind the gadgets successful the RecyclerView!

The SortedList interacts with the Adapter done a Callback people which you person to instrumentality:

backstage last SortedList.Callback<ExampleModel> mCallback = fresh SortedList.Callback<ExampleModel>() { @Override national void onInserted(int assumption, int number) { mAdapter.notifyItemRangeInserted(assumption, number); } @Override national void onRemoved(int assumption, int number) { mAdapter.notifyItemRangeRemoved(assumption, number); } @Override national void onMoved(int fromPosition, int toPosition) { mAdapter.notifyItemMoved(fromPosition, toPosition); } @Override national void onChanged(int assumption, int number) { mAdapter.notifyItemRangeChanged(assumption, number); } @Override national int comparison(ExampleModel a, ExampleModel b) { instrument mComparator.comparison(a, b); } @Override national boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) { instrument oldItem.equals(newItem); } @Override national boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) { instrument item1.getId() == item2.getId(); } } 

Successful the strategies astatine the apical of the callback similar onMoved, onInserted, and many others. you person to call the equal notify technique of your Adapter. The 3 strategies astatine the bottommost comparison, areContentsTheSame and areItemsTheSame you person to instrumentality in accordance to what benignant of objects you privation to show and successful what command these objects ought to look connected the surface.

Fto’s spell done these strategies 1 by 1:

@Override national int comparison(ExampleModel a, ExampleModel b) { instrument mComparator.comparison(a, b); } 

This is the comparison() methodology I talked astir earlier. Successful this illustration I americium conscionable passing the call to a Comparator which compares the 2 fashions. If you privation the objects to look successful alphabetical command connected the surface. This comparator mightiness expression similar this:

backstage static last Comparator<ExampleModel> ALPHABETICAL_COMPARATOR = fresh Comparator<ExampleModel>() { @Override national int comparison(ExampleModel a, ExampleModel b) { instrument a.getText().compareTo(b.getText()); } }; 

Present fto’s return a expression astatine the adjacent technique:

@Override national boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) { instrument oldItem.equals(newItem); } 

The intent of this technique is to find if the contented of a exemplary has modified. The SortedList makes use of this to find if a alteration case wants to beryllium invoked - successful another phrases if the RecyclerView ought to crossfade the aged and fresh interpretation. If you exemplary lessons person a accurate equals() and hashCode() implementation you tin normally conscionable instrumentality it similar supra. If we adhd an equals() and hashCode() implementation to the ExampleModel people it ought to expression thing similar this:

national people ExampleModel implements SortedListAdapter.ViewModel { backstage last agelong mId; backstage last Drawstring mText; national ExampleModel(agelong id, Drawstring matter) { mId = id; mText = matter; } national agelong getId() { instrument mId; } national Drawstring getText() { instrument mText; } @Override national boolean equals(Entity o) { if (this == o) instrument actual; if (o == null || getClass() != o.getClass()) instrument mendacious; ExampleModel exemplary = (ExampleModel) o; if (mId != exemplary.mId) instrument mendacious; instrument mText != null ? mText.equals(exemplary.mText) : exemplary.mText == null; } @Override national int hashCode() { int consequence = (int) (mId ^ (mId >>> 32)); consequence = 31 * consequence + (mText != null ? mText.hashCode() : zero); instrument consequence; } } 

Speedy broadside line: About IDE’s similar Android Workplace, IntelliJ and Eclipse person performance to make equals() and hashCode() implementations for you astatine the estate of a fastener! Truthful you don’t person to instrumentality them your self. Expression ahead connected the net however it plant successful your IDE!

Present fto’s return a expression astatine the past methodology:

@Override national boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) { instrument item1.getId() == item2.getId(); } 

The SortedList makes use of this technique to cheque if 2 objects mention to the aforesaid happening. Successful easiest status (with out explaining however the SortedList plant) this is utilized to find if an entity is already contained successful the Database and if both an adhd, decision oregon alteration animation wants to beryllium performed. If your fashions person an id you would normally comparison conscionable the id successful this methodology. If they don’t you demand to fig retired any another manner to cheque this, however nevertheless you extremity ahead implementing this relies upon connected your circumstantial app. Normally it is the easiest action to springiness each fashions an id - that may for illustration beryllium the capital cardinal tract if you are querying the information from a database.

With the SortedList.Callback appropriately carried out we tin make an case of the SortedList:

last SortedList<ExampleModel> database = fresh SortedList<>(ExampleModel.people, mCallback); 

Arsenic the archetypal parameter successful the constructor of the SortedList you demand to walk the people of your fashions. The another parameter is conscionable the SortedList.Callback we outlined supra.

Present fto’s acquire behind to concern: If we instrumentality the Adapter with a SortedList it ought to expression thing similar this:

national people ExampleAdapter extends RecyclerView.Adapter<ExampleViewHolder> { backstage last SortedList<ExampleModel> mSortedList = fresh SortedList<>(ExampleModel.people, fresh SortedList.Callback<ExampleModel>() { @Override national int comparison(ExampleModel a, ExampleModel b) { instrument mComparator.comparison(a, b); } @Override national void onInserted(int assumption, int number) { notifyItemRangeInserted(assumption, number); } @Override national void onRemoved(int assumption, int number) { notifyItemRangeRemoved(assumption, number); } @Override national void onMoved(int fromPosition, int toPosition) { notifyItemMoved(fromPosition, toPosition); } @Override national void onChanged(int assumption, int number) { notifyItemRangeChanged(assumption, number); } @Override national boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) { instrument oldItem.equals(newItem); } @Override national boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) { instrument item1.getId() == item2.getId(); } }); backstage last LayoutInflater mInflater; backstage last Comparator<ExampleModel> mComparator; national ExampleAdapter(Discourse discourse, Comparator<ExampleModel> comparator) { mInflater = LayoutInflater.from(discourse); mComparator = comparator; } @Override national ExampleViewHolder onCreateViewHolder(ViewGroup genitor, int viewType) { last ItemExampleBinding binding = ItemExampleBinding.inflate(inflater, genitor, mendacious); instrument fresh ExampleViewHolder(binding); } @Override national void onBindViewHolder(ExampleViewHolder holder, int assumption) { last ExampleModel exemplary = mSortedList.acquire(assumption); holder.hindrance(exemplary); } @Override national int getItemCount() { instrument mSortedList.measurement(); } } 

The Comparator utilized to kind the point is handed successful done the constructor truthful we tin usage the aforesaid Adapter equal if the objects are expected to beryllium displayed successful a antithetic command.

Present we are about finished! However we archetypal demand a manner to adhd oregon distance objects to the Adapter. For this intent we tin adhd strategies to the Adapter which let america to adhd and distance gadgets to the SortedList:

national void adhd(ExampleModel exemplary) { mSortedList.adhd(exemplary); } national void distance(ExampleModel exemplary) { mSortedList.distance(exemplary); } national void adhd(Database<ExampleModel> fashions) { mSortedList.addAll(fashions); } national void distance(Database<ExampleModel> fashions) { mSortedList.beginBatchedUpdates(); for (ExampleModel exemplary : fashions) { mSortedList.distance(exemplary); } mSortedList.endBatchedUpdates(); } 

We don’t demand to call immoderate notify strategies present due to the fact that the SortedList already does this for done the SortedList.Callback! Speech from that the implementation of these strategies is beautiful consecutive guardant with 1 objection: the distance technique which removes a Database of fashions. Since the SortedList has lone 1 distance technique which tin distance a azygous entity we demand to loop complete the database and distance the fashions 1 by 1. Calling beginBatchedUpdates() astatine the opening batches each the adjustments we are going to brand to the SortedList unneurotic and improves show. Once we call endBatchedUpdates() the RecyclerView is notified astir each the modifications astatine erstwhile.

Moreover what you person to realize is that if you adhd an entity to the SortedList and it is already successful the SortedList it received’t beryllium added once more. Alternatively the SortedList makes use of the areContentsTheSame() technique to fig retired if the entity has modified - and if it has the point successful the RecyclerView volition beryllium up to date.

Anyhow, what I normally like is 1 technique which permits maine to regenerate each objects successful the RecyclerView astatine erstwhile. Distance all the things which is not successful the Database and adhd each gadgets which are lacking from the SortedList:

national void replaceAll(Database<ExampleModel> fashions) { mSortedList.beginBatchedUpdates(); for (int i = mSortedList.dimension() - 1; i >= zero; i--) { last ExampleModel exemplary = mSortedList.acquire(i); if (!fashions.comprises(exemplary)) { mSortedList.distance(exemplary); } } mSortedList.addAll(fashions); mSortedList.endBatchedUpdates(); } 

This methodology once more batches each updates unneurotic to addition show. The archetypal loop is successful reverse since eradicating an point astatine the commencement would messiness ahead the indexes of each gadgets that travel ahead last it and this tin pb successful any situations to issues similar information inconsistencies. Last that we conscionable adhd the Database to the SortedList utilizing addAll() to adhd each gadgets which are not already successful the SortedList and - conscionable similar I described supra - replace each gadgets that are already successful the SortedList however person modified.

And with that the Adapter is absolute. The entire happening ought to expression thing similar this:

national people ExampleAdapter extends RecyclerView.Adapter<ExampleViewHolder> { backstage last SortedList<ExampleModel> mSortedList = fresh SortedList<>(ExampleModel.people, fresh SortedList.Callback<ExampleModel>() { @Override national int comparison(ExampleModel a, ExampleModel b) { instrument mComparator.comparison(a, b); } @Override national void onInserted(int assumption, int number) { notifyItemRangeInserted(assumption, number); } @Override national void onRemoved(int assumption, int number) { notifyItemRangeRemoved(assumption, number); } @Override national void onMoved(int fromPosition, int toPosition) { notifyItemMoved(fromPosition, toPosition); } @Override national void onChanged(int assumption, int number) { notifyItemRangeChanged(assumption, number); } @Override national boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) { instrument oldItem.equals(newItem); } @Override national boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) { instrument item1 == item2; } }); backstage last Comparator<ExampleModel> mComparator; backstage last LayoutInflater mInflater; national ExampleAdapter(Discourse discourse, Comparator<ExampleModel> comparator) { mInflater = LayoutInflater.from(discourse); mComparator = comparator; } @Override national ExampleViewHolder onCreateViewHolder(ViewGroup genitor, int viewType) { last ItemExampleBinding binding = ItemExampleBinding.inflate(mInflater, genitor, mendacious); instrument fresh ExampleViewHolder(binding); } @Override national void onBindViewHolder(ExampleViewHolder holder, int assumption) { last ExampleModel exemplary = mSortedList.acquire(assumption); holder.hindrance(exemplary); } national void adhd(ExampleModel exemplary) { mSortedList.adhd(exemplary); } national void distance(ExampleModel exemplary) { mSortedList.distance(exemplary); } national void adhd(Database<ExampleModel> fashions) { mSortedList.addAll(fashions); } national void distance(Database<ExampleModel> fashions) { mSortedList.beginBatchedUpdates(); for (ExampleModel exemplary : fashions) { mSortedList.distance(exemplary); } mSortedList.endBatchedUpdates(); } national void replaceAll(Database<ExampleModel> fashions) { mSortedList.beginBatchedUpdates(); for (int i = mSortedList.measurement() - 1; i >= zero; i--) { last ExampleModel exemplary = mSortedList.acquire(i); if (!fashions.accommodates(exemplary)) { mSortedList.distance(exemplary); } } mSortedList.addAll(fashions); mSortedList.endBatchedUpdates(); } @Override national int getItemCount() { instrument mSortedList.dimension(); } } 

The lone happening lacking present is to instrumentality the filtering!


Implementing the filter logic

To instrumentality the filter logic we archetypal person to specify a Database of each imaginable fashions. For this illustration I make a Database of ExampleModel situations from an array of films:

backstage static last Drawstring[] Motion pictures = fresh Drawstring[]{ ... }; backstage static last Comparator<ExampleModel> ALPHABETICAL_COMPARATOR = fresh Comparator<ExampleModel>() { @Override national int comparison(ExampleModel a, ExampleModel b) { instrument a.getText().compareTo(b.getText()); } }; backstage ExampleAdapter mAdapter; backstage Database<ExampleModel> mModels; backstage RecyclerView mRecyclerView; @Override protected void onCreate(Bundle savedInstanceState) { ace.onCreate(savedInstanceState); mBinding = DataBindingUtil.setContentView(this, R.structure.activity_main); mAdapter = fresh ExampleAdapter(this, ALPHABETICAL_COMPARATOR); mBinding.recyclerView.setLayoutManager(fresh LinearLayoutManager(this)); mBinding.recyclerView.setAdapter(mAdapter); mModels = fresh ArrayList<>(); for (Drawstring film : Films) { mModels.adhd(fresh ExampleModel(film)); } mAdapter.adhd(mModels); } 

Thing particular going connected present, we conscionable instantiate the Adapter and fit it to the RecyclerView. Last that we make a Database of fashions from the film names successful the Films array. Past we adhd each the fashions to the SortedList.

Present we tin spell backmost to onQueryTextChange() which we outlined earlier and commencement implementing the filter logic:

@Override national boolean onQueryTextChange(Drawstring question) { last Database<ExampleModel> filteredModelList = filter(mModels, question); mAdapter.replaceAll(filteredModelList); mBinding.recyclerView.scrollToPosition(zero); instrument actual; } 

This is once more beautiful consecutive guardant. We call the methodology filter() and walk successful the Database of ExampleModels arsenic fine arsenic the question drawstring. We past call replaceAll() connected the Adapter and walk successful the filtered Database returned by filter(). We besides person to call scrollToPosition(zero) connected the RecyclerView to guarantee that the person tin ever seat each objects once looking for thing. Other the RecyclerView mightiness act successful a scrolled behind assumption piece filtering and subsequently fell a fewer objects. Scrolling to the apical ensures a amended person education piece looking out.

The lone happening near to bash present is to instrumentality filter() itself:

backstage static Database<ExampleModel> filter(Database<ExampleModel> fashions, Drawstring question) { last Drawstring lowerCaseQuery = question.toLowerCase(); last Database<ExampleModel> filteredModelList = fresh ArrayList<>(); for (ExampleModel exemplary : fashions) { last Drawstring matter = exemplary.getText().toLowerCase(); if (matter.incorporates(lowerCaseQuery)) { filteredModelList.adhd(exemplary); } } instrument filteredModelList; } 

The archetypal happening we bash present is call toLowerCase() connected the question drawstring. We don’t privation our hunt relation to beryllium lawsuit delicate and by calling toLowerCase() connected each strings we comparison we tin guarantee that we instrument the aforesaid outcomes careless of lawsuit. It past conscionable iterates done each the fashions successful the Database we handed into it and checks if the question drawstring is contained successful the matter of the exemplary. If it is past the exemplary is added to the filtered Database.

And that’s it! The supra codification volition tally connected API flat 7 and supra and beginning with API flat eleven you acquire point animations for escaped!

I recognize that this is a precise elaborate statement which most likely makes this entire happening look much complex than it truly is, however location is a manner we tin generalize this entire job and brand implementing an Adapter based mostly connected a SortedList overmuch easier.


Generalizing the job and simplifying the Adapter

Successful this conception I americium not going to spell into overmuch item - partially due to the fact that I americium moving ahead in opposition to the quality bounds for solutions connected Stack Overflow however besides due to the fact that about of it already defined supra - however to summarize the modifications: We tin carried out a basal Adapter people which already takes attention of dealing with the SortedList arsenic fine arsenic binding fashions to ViewHolder cases and offers a handy manner to instrumentality an Adapter based mostly connected a SortedList. For that we person to bash 2 issues:

  • We demand to make a ViewModel interface which each exemplary lessons person to instrumentality
  • We demand to make a ViewHolder subclass which defines a hindrance() methodology the Adapter tin usage to hindrance fashions routinely.

This permits america to conscionable direction connected the contented which is expected to beryllium displayed successful the RecyclerView by conscionable implementing the fashions and location corresponding ViewHolder implementations. Utilizing this basal people we don’t person to concern astir the intricate particulars of the Adapter and its SortedList.

SortedListAdapter

Due to the fact that of the quality bounds for solutions connected StackOverflow I tin’t spell done all measure of implementing this basal people oregon equal adhd the afloat origin codification present, however you tin discovery the afloat origin codification of this basal people - I known as it SortedListAdapter - successful this GitHub Gist.

To brand your beingness elemental I person printed a room connected jCenter which incorporates the SortedListAdapter! If you privation to usage it past each you demand to bash is adhd this dependency to your app’s physique.gradle record:

compile 'com.github.wrdlbrnft:sorted-database-adapter:zero.2.zero.1' 

You tin discovery much accusation astir this room connected the room homepage.

Utilizing the SortedListAdapter

To usage the SortedListAdapter we person to brand 2 adjustments:

  • Alteration the ViewHolder truthful that it extends SortedListAdapter.ViewHolder. The kind parameter ought to beryllium the exemplary which ought to beryllium certain to this ViewHolder - successful this lawsuit ExampleModel. You person to hindrance information to your fashions successful performBind() alternatively of hindrance().

    national people ExampleViewHolder extends SortedListAdapter.ViewHolder<ExampleModel> { backstage last ItemExampleBinding mBinding; national ExampleViewHolder(ItemExampleBinding binding) { ace(binding.getRoot()); mBinding = binding; } @Override protected void performBind(ExampleModel point) { mBinding.setModel(point); } } 
    
  • Brand certain that each your fashions instrumentality the ViewModel interface:

    national people ExampleModel implements SortedListAdapter.ViewModel { ... } 
    

Last that we conscionable person to replace the ExampleAdapter to widen SortedListAdapter and distance all the pieces we don’t demand anymore. The kind parameter ought to beryllium the kind of exemplary you are running with - successful this lawsuit ExampleModel. However if you are running with antithetic varieties of fashions past fit the kind parameter to ViewModel.

national people ExampleAdapter extends SortedListAdapter<ExampleModel> { national ExampleAdapter(Discourse discourse, Comparator<ExampleModel> comparator) { ace(discourse, ExampleModel.people, comparator); } @Override protected ViewHolder<? extends ExampleModel> onCreateViewHolder(LayoutInflater inflater, ViewGroup genitor, int viewType) { last ItemExampleBinding binding = ItemExampleBinding.inflate(inflater, genitor, mendacious); instrument fresh ExampleViewHolder(binding); } @Override protected boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) { instrument item1.getId() == item2.getId(); } @Override protected boolean areItemContentsTheSame(ExampleModel oldItem, ExampleModel newItem) { instrument oldItem.equals(newItem); } } 

Last that we are achieved! Nevertheless 1 past happening to notation: The SortedListAdapter does not person the aforesaid adhd(), distance() oregon replaceAll() strategies our first ExampleAdapter had. It makes use of a abstracted Application entity to modify the gadgets successful the database which tin beryllium accessed done the edit() methodology. Truthful if you privation to distance oregon adhd objects you person to call edit() past adhd and distance the gadgets connected this Application case and erstwhile you are carried out, call perpetrate() connected it to use the adjustments to the SortedList:

mAdapter.edit() .distance(modelToRemove) .adhd(listOfModelsToAdd) .perpetrate(); 

Each modifications you brand this manner are batched unneurotic to addition show. The replaceAll() technique we carried out successful the chapters supra is besides immediate connected this Application entity:

mAdapter.edit() .replaceAll(mModels) .perpetrate(); 

If you bury to call perpetrate() past no of your adjustments volition beryllium utilized!