Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
288 views
in Technique[技术] by (71.8m points)

android - Add a search filter on RecyclerView with Cards?

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...