Hilal Ahmad
Hilal Ahmad

Reputation: 124

How to add search filter to RecyclerView using with DiffUtil

I have a recyclerview in my app in which I am using DiffUtil to load all the items, but now I want to add a search filter to that recyclerview how can I implement a search filter in RecyclerView which are adding items to the adapter using DiffUtil.

I tried it like this but it doesn't work.

public class BookmarksAdapter extends ListAdapter<Bookmark, 
BookmarksAdapter.ViewHolder> implements Filterable {

private OnBookmarkClickListener bookmarkClickListener;

public BookmarksAdapter() {
    super(differCallBack);
}

private static final DiffUtil.ItemCallback<Bookmark> differCallBack = new 
DiffUtil.ItemCallback<Bookmark>() {

    @Override
    public boolean areItemsTheSame(@NonNull @NotNull Bookmark oldItem, @NonNull @NotNull Bookmark newItem) {
        return oldItem.getId() == newItem.getId();
    }

    @Override
    public boolean areContentsTheSame(@NonNull @NotNull Bookmark oldItem, @NonNull @NotNull Bookmark newItem) {
        return oldItem.getPostTitle().equals(newItem.getPostTitle())
                && oldItem.getPostUrl().equals(newItem.getPostUrl());
    }
};

private AsyncListDiffer<Bookmark> differ = new AsyncListDiffer<>(this, differCallBack);

@NonNull
@NotNull
@Override
public ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(
            R.layout.bookmarks_list_items,
            parent,
            false
    );
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull @NotNull ViewHolder holder, int position) {
    Bookmark currentItem = getItem(position);
    holder.tvTitle.setText(currentItem.getPostTitle());

    holder.itemView.setOnClickListener(v -> {
        if (bookmarkClickListener != null){
            bookmarkClickListener.onBookmarkClick(currentItem);
        }
    });
}

@Override
public Filter getFilter() {
    return bookmarksFilter;
}

public class ViewHolder extends RecyclerView.ViewHolder{
    TextView tvTitle;

    public ViewHolder(@NonNull @NotNull View itemView) {
        super(itemView);
        tvTitle = itemView.findViewById(R.id.tvTitle);
    }
}

public interface OnBookmarkClickListener {
    void onBookmarkClick(Bookmark bookmark);
}

public void setOnBookmarkClickListener(OnBookmarkClickListener clickListener) {
    this.bookmarkClickListener = clickListener;
}

List<Bookmark> bookmarkListFull = new ArrayList<>();

private Filter bookmarksFilter = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        List<Bookmark> filteredList = new ArrayList<>();

        Utils.infoLog("SearchTerm", "Search for: " + constraint);

        if (constraint == null || constraint.length() == 0) {
            filteredList.addAll(bookmarkListFull);
        } else {
            String filterPattern = constraint.toString().toLowerCase().trim();

            for (Bookmark bookmark : differ.getCurrentList()) {
                if (bookmark.getPostTitle().toLowerCase().contains(filterPattern)) {
                    filteredList.add(bookmark);
                }
            }
        }

        FilterResults results = new FilterResults();
        results.values = filteredList;
        Utils.infoLog("SearchTerm", "FilteredList1: " + results.values);
        return results;

    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        differ.submitList((List)results.values);
        Utils.infoLog("SearchTerm", "FilteredList2: " + results.values);
        notifyDataSetChanged();
    }
};

}

How can I implement search filter in this recyclerview?

Upvotes: 3

Views: 492

Answers (0)

Related Questions