Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add a search filter on RecyclerView with Cards?

Tags:

I found solutions for filters on ListView and SearchView on RecyclerView separately, but I wish to combine them. Is it even possible?

like image 757
priyank Avatar asked Apr 22 '15 08:04

priyank


People also ask

How do I add a separator in RecyclerView?

We have to create a default Divider using addItemDecoration() method with the RecyclerView instance, we need to pass the ItemDecoration(in this case it is DividerItemDecoration()) instance and the orientation of the LayoutManager(in this case it is vertical) of the recycler view.


2 Answers

Yes it is possible Your RecyclerView.Adapter can implement Filterable. After that you have to override Filter getFilter() method.

You have to define your own filter as is shown in the code below:

@Override public Filter getFilter() {     return new YourFilterClass(); } 

YourFilterClass

class YourFilterClass extends Filter {          @Override         protected FilterResults performFiltering(CharSequence constraint) {             //Here you have to implement filtering way             final FilterResults results = new FilterResults();             //logic to filtering             results.values = ...             results.count = ...             return results;         }          @Override         protected void publishResults(CharSequence constraint, FilterResults results) {             // here you can use result - (f.e. set in in adapter list)         } } 

Example

public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.ViewHolder> implements Filterable {      private final List<User> userList;      private final List<User> filteredUserList;      private UserFilter userFilter;      public UserListAdapter(Context context) {         this.userList =new ArrayList<>();         this.filteredUserList = new ArrayList<>();     }       ///... other methods      @Override     public Filter getFilter() {        if(userFilter == null)              userFilter = new UserFilter(this, userList);         return userFilter;     }      private static class UserFilter extends Filter {          private final UserListAdapter adapter;          private final List<User> originalList;          private final List<User> filteredList;          private UserFilter(UserListAdapter adapter, List<User> originalList) {             super();             this.adapter = adapter;             this.originalList = new LinkedList<>(originalList);             this.filteredList = new ArrayList<>();         }          @Override         protected FilterResults performFiltering(CharSequence constraint) {             filteredList.clear();             final FilterResults results = new FilterResults();              if (constraint.length() == 0) {                 filteredList.addAll(originalList);             } else {                 final String filterPattern = constraint.toString().toLowerCase().trim();                  for (final User user : originalList) {                     if (user.getName().contains(filterPattern)) {                         filteredList.add(user);                     }                 }             }             results.values = filteredList;             results.count = filteredList.size();             return results;         }          @Override         protected void publishResults(CharSequence constraint, FilterResults results) {             adapter.filteredUserList.clear();             adapter.filteredUserList.addAll((ArrayList<User>) results.values);             adapter.notifyDataSetChanged();         }     } } 

After that in the place when you want to filtering call:

userListAdapter.getFilter().filter(text) 
like image 179
Konrad Krakowiak Avatar answered Sep 19 '22 15:09

Konrad Krakowiak


Inside Fragment Class declare that:

protected List<User> mDataset; protected List<User> mDataOrigin; 

then inside onCreate add same source destination to both dataSet ant dataOrigin

mDataset = getObjectsFromDB(); mDataOrigin = getObjectsFromDB(); 

Finally use the magic function:

private void filterRecyclerView(String charText){     charText = charText.toLowerCase();     clearDataSet();     if (charText.length() == 0) {         mDataset.addAll(mDataOrigin);     } else {         for (User user : mDataOrigin) {             if (user.getName().toLowerCase().contains(charText)) {                 mDataset.add(user);             }         }     }     mAdapter.notifyDataSetChanged(); } 

Notice User is the list content you can replace with your Object have fun :)

like image 25
Mostafa Anter Avatar answered Sep 18 '22 15:09

Mostafa Anter