In this blog , we will learn on how to implement the search on items of a recycler view and show only the items that are related to the key value searched for.
APPROACH :
- Create a class say MyFilter that extends Filter class.
- Make a constructor of MyFilter that takes in two parameters viz, Adapter associated with your recycler view and list that is currently associated with the adapter.
- Override the “performFiltering” method and implement the logic on which you want to implement the search.
- Override the “publishResults” method and in this method you will typecast the default filterResults.values to the list of objects associated with your Adapter.
- Make Adapterclass of your RecyclerView implements the Filterable interface.
- Override the “getFilter” method and this method return the object of your Filter class (MyFilter class in our case).
- Now set the “setOnQueryTextListener” on your search view and in “onQueryTextSubmit”
“onQueryTextChange” methods get the instance of filter by calling the getFilter Method.
And this will filter the items in your recycler view. Now let’s have a look at the code to get a better understanding.Before this a brief guide to the code snippet.
The code snippet contains only the filtering part . You need to implement the three basic methods of RecyclerView.Adapter yourself. The user is my Object class(or model class) and a list of user is associated with the adapter. I have implemented the search on the basis of name only.
CODE :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements Filterable { private final Context mContext; private List<User> myList; private List<User> mFilteredList; public MyFilter mFilter; public MyAdapter(Context mContext, List<User> mList) { this.mContext = mContext; this.myList= mList; this.mFilteredList = new ArrayList<User>(); } @Override public Filter getFilter() { if (mFilter == null){ mFilteredList.clear(); mFilteredList.addAll(this.myList); mFilter = new MyAdapter.MyFilter(this,mFilteredList); } return mFilter; } private static class MyFilter extends Filter { private final MyAdapter myAdapter; private final List<User> originalList; private final List<User> filteredList; private MyFilter(MyAdapter myAdapter, List<User> originalList) { this.myAdapter = myAdapter; this.originalList = originalList; this.filteredList = new ArrayList<User>(); } @Override protected FilterResults performFiltering(CharSequence charSequence) { filteredList.clear(); final FilterResults results = new FilterResults(); if (charSequence.length() == 0){ filteredList.addAll(originalList); }else { final String filterPattern = charSequence.toString().toLowerCase().trim(); for ( User user : originalList){ if (user.getName().toLowerCase().contains(filterPattern)){ filteredList.add(user); } } } results.values = filteredList; results.count = filteredList.size(); return results; } @Override protected void publishResults(CharSequence charSequence, FilterResults filterResults) { myAdapter.myList.clear(); myAdapter.myList.addAll((ArrayList<User>)filterResults.values); myAdapter.notifyDataSetChanged(); } } } |
Code for the User.class :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class User { String name, email, phone_number; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhone_number() { return phone_number; } public void setPhone_number(String phone_number) { this.phone_number = phone_number; } } |
and finally in your search view add this code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { myAdapter.getFilter().filter(query); return true; } @Override public boolean onQueryTextChange(String newText) { myAdapter.getFilter().filter(newText); return true; } }); |