I found solutions for filters on ListView
and SearchView
on RecyclerView
separately, but I wish to combine them. Is it even possible?
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.
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) } }
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)
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With