1

I am trying to allow users to search for certain items from my recycle view (which gets populated from firebase). Everything Is working fine the only problem that I'm having right now is whenever i try to search for something my recycle view items gets duplicated. Could you tell me what I'm doing wrong here?

public class NewsFeedAdapter extends RecyclerView.Adapter<NewsFeedAdapter.ViewHolder> implements Filterable {
    private Context context;
    private ArrayList<Post> bookData;
    private ArrayList<Post> bookDataFull;



    public NewsFeedAdapter(Context context, ArrayList<Post> bookDatas) {
        this.context = context;
        this.bookData = bookDatas;
        this.bookDataFull = new ArrayList<>(bookDatas);
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.news_feed_row, viewGroup, false));

    }

    //Loads data into views
    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {

        Glide
                .with(context)
                .load(bookData.get(i).getBookImage())
                .placeholder(R.drawable.bookshelf)
                .fitCenter()
                .into(viewHolder.bookImageView);


        viewHolder.bookTitle.setText(bookData.get(i).getBookTitle());
        viewHolder.bookAuthor.setText(bookData.get(i).getBookAuthor());





    }

    @Override
    public int getItemCount() {
        return bookData.size();
    }




    //links up ui elements
    class ViewHolder extends RecyclerView.ViewHolder {
        private ImageView bookImageView;
        private TextView bookTitle, bookAuthor;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            bookTitle = itemView.findViewById(R.id.bookTitleTv);
            bookAuthor = itemView.findViewById(R.id.bookAuthorTv);
            bookImageView = itemView.findViewById(R.id.bookImageView);
        }
    }

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

    private Filter exampleFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            ArrayList<Post> filteredList = new ArrayList<>();


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

                for (Post item : bookData) {

                    if (item.getBookAuthor().toLowerCase().contains(filterPattern)) {
                        filteredList.add(item);

                    }

                    if(item.getBookTitle().toLowerCase().contains(filterPattern)){
                        filteredList.add(item);
                    }

                }
            }

            FilterResults results = new FilterResults();
            results.values = filteredList;

            return results;
        }
        //updates UI

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            bookData.clear();
            bookData.addAll((List) results.values);
            notifyDataSetChanged();

        }
    };
}

3 Answers3

0

Please use following code. I hope it will works perfectly.

public class NewsFeedAdapter extends RecyclerView.Adapter<NewsFeedAdapter.ViewHolder> implements Filterable {
    private Context context;
    private ArrayList<Post> filteredBookData = new ArrayList<>();
    private ArrayList<Post> bookDataFull = new ArrayList<>();

    public NewsFeedAdapter(Context context, ArrayList<Post> bookDatas) {
        this.context = context;
        this.filteredBookData = bookDatas;
        this.bookDataFull = bookDatas;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.news_feed_row, viewGroup, false));

    }
    //Loads data into views
    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {

        Glide
                .with(context)
                .load(filteredBookData.get(i).getBookImage())
                .placeholder(R.drawable.bookshelf)
                .fitCenter()
                .into(viewHolder.bookImageView);

        viewHolder.bookTitle.setText(filteredBookData.get(i).getBookTitle());
        viewHolder.bookAuthor.setText(filteredBookData.get(i).getBookAuthor());
    }

    @Override
    public int getItemCount() {
        return filteredBookData.size();
    }




    //links up ui elements
    class ViewHolder extends RecyclerView.ViewHolder {
        private ImageView bookImageView;
        private TextView bookTitle, bookAuthor;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            bookTitle = itemView.findViewById(R.id.bookTitleTv);
            bookAuthor = itemView.findViewById(R.id.bookAuthorTv);
            bookImageView = itemView.findViewById(R.id.bookImageView);
        }
    }

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

    private Filter exampleFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            ArrayList<Post> filteredList = new ArrayList<>();
            String filterPattern = constraint.toString().toLowerCase().trim();

            if (constraint == null || constraint.length() == 0) {
                filteredList.addAll(bookDataFull);
            } else {

                for (Post item : bookDataFull) {

                    if (item.getBookAuthor().toLowerCase().contains(filterPattern)) {
                        filteredList.add(item);

                    }

                    if(item.getBookTitle().toLowerCase().contains(filterPattern)){
                        filteredList.add(item);
                    }

                }
            }

            FilterResults results = new FilterResults();
            results.values = filteredList;
            return results;
        }
        //updates UI

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            filteredBookData = (ArrayList<Post>) results.values;
            notifyDataSetChanged();

        }
    };
}
Rezaul Islam
  • 113
  • 1
  • 8
0

Modify your NewsFeedAdapter like the following.

public class NewsFeedAdapter extends RecyclerView.Adapter<NewsFeedAdapter.ViewHolder> implements Filterable {
    private Context context;
    private ArrayList<Post> bookData;
    private ArrayList<Post> bookDataFilter;



    public NewsFeedAdapter(Context context, ArrayList<Post> bookDatas) {
        this.context = context;
        this.bookData = bookDatas;
        this.bookDataFilter = bookDatas;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.news_feed_row, viewGroup, false));

    }

    //Loads data into views
    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {

        Glide
                .with(context)
                .load(bookDataFilter.get(i).getBookImage())
                .placeholder(R.drawable.bookshelf)
                .fitCenter()
                .into(viewHolder.bookImageView);


        viewHolder.bookTitle.setText(bookDataFilter.get(i).getBookTitle());
        viewHolder.bookAuthor.setText(bookDataFilter.get(i).getBookAuthor());





    }

    @Override
    public int getItemCount() {
        return bookDataFilter.size();
    }




    //links up ui elements
    class ViewHolder extends RecyclerView.ViewHolder {
        private ImageView bookImageView;
        private TextView bookTitle, bookAuthor;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            bookTitle = itemView.findViewById(R.id.bookTitleTv);
            bookAuthor = itemView.findViewById(R.id.bookAuthorTv);
            bookImageView = itemView.findViewById(R.id.bookImageView);
        }
    }

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

    private Filter exampleFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            if (constraint == null || constraint.length() == 0) {
                bookDataFilter = bookData;
            } else {
                ArrayList<Post> filteredList = new ArrayList<>();
                String filterPattern = constraint.toString().toLowerCase().trim();

                for (Post item : bookData) {

                    if (item.getBookAuthor().toLowerCase().contains(filterPattern)) {
                        filteredList.add(item);

                    }

                    if(item.getBookTitle().toLowerCase().contains(filterPattern)){
                        filteredList.add(item);
                    }

                }
                bookDataFilter = filteredList; // add this line here
            }

            FilterResults results = new FilterResults();
            results.values = bookDataFilter;

            return results;
        }
        //updates UI

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            bookDataFilter = (ArrayList<Post>) results.values;
            notifyDataSetChanged();

        }
    };
}
Jakir Hossain
  • 3,426
  • 1
  • 11
  • 25
0

This is happening because,In your filter you are using the same bookData list which used for filtering.This list is clearing every time you do a filter.Please use bookDataFull which is not modifying.Change your filter code to the following.

private Filter exampleFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            ArrayList<Post> filteredList = new ArrayList<>();


            if (constraint == null || constraint.length() == 0) {
                //use bookDataFull which is not modifying
                filteredList.addAll(bookDataFull);
            } else {
                String filterPattern = constraint.toString().toLowerCase().trim();
                //use bookDataFull which is not modifying
                for (Post item : bookDataFull) {

                    if (item.getBookAuthor().toLowerCase().contains(filterPattern)) {
                        filteredList.add(item);

                    }

                    if (item.getBookTitle().toLowerCase().contains(filterPattern)) {
                        filteredList.add(item);
                    }

                }
            }

            FilterResults results = new FilterResults();
            results.values = filteredList;

            return results;
        }
        //updates UI

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            bookData.clear();
            bookData.addAll((List) results.values);
            notifyDataSetChanged();

        }
    };
Jinesh Francis
  • 2,660
  • 2
  • 16
  • 34