0

I use a recyclerview which I modify thanks to Diffutils. Unfortunately, when I filter my recyclerview and delete items, the index of the deleted items does not match that of my list.

For instance, if I have 3 items: [a, ab,abc] with the index (0,1,2) and I filter with the word "ab", the newly displayed items are [ab, abc] with the index (0,1) so when I try to delete items from the recyclerView, index are wrong.


This is a part of my recycler code

public class NoteListAdapter extends RecyclerView.Adapter<NoteListAdapter.NoteListViewHolder> implements Filterable {

    private List<Note> noteList;
    private List<Note> noteListFull;
    private NoteEventListener listener;
    private CustomFilter filter;

    public NoteListAdapter(List<Note> noteList, NoteEventListener noteEventListener) {
        this.noteList = noteList;
        this.noteListFull = noteList;
        this.listener = noteEventListener;
    }

    public void updateList(List<Note> newList) {
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtils(this.noteList, newList));
        noteList.clear();
        noteList.addAll(newList);
        diffResult.dispatchUpdatesTo(this);
    }

    public void insertList(List<Integer> index, List<Note> newList) {
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtils(this.noteList, newList));
        for (int i =0; i < newList.size(); i++)
            noteList.add(index.get(i), newList.get(i));
        diffResult.dispatchUpdatesTo(this);
    }


    @Override
    public void onBindViewHolder(@NonNull final NoteListViewHolder holder, int position) {
        final Note note = noteList.get(position);

        if (note != null) {
            holder.itemView.setOnClickListener(v -> listener.onNoteClick(position, note));
            holder.itemView.setOnLongClickListener(v -> {
                listener.onNoteLongClick(position, note);
                return true;
            });
        }
    }


    @Override
    public Filter getFilter() {
        if(filter == null)
            filter = new CustomFilter();
        return filter;
    }

    class CustomFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();

            if(constraint == null || constraint.length() == 0) {
                filterResults.values = noteListFull;
                filterResults.count = noteListFull.size();
            }
            else {
                String pattern = constraint.toString().toLowerCase();
                List<Note> filters = new ArrayList<>();

                for(Note item: noteListFull) {
                    if (item.getTitle().toLowerCase().contains(pattern)) {
                        Note n = new Note(item.getTitle(), item.getContent());
                        filters.add(n);
                    }
                }
                filterResults.values = filters;
                filterResults.count = filters.size();
            }

            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            noteList = (List) results.values;
            notifyDataSetChanged();
        }
    }

}

And this is my code when I delete an item:

private void delete_note() {
     // Position of all selected items ready to be deleted (but with wrong index)
     List<Integer> selectedItems = noteListAdapter.getSelectedItems();

     List<Note> temp = new ArrayList<>(notes);
     List<Note> deletedItems = selectedItems.stream().map(notes::get).collect(Collectors.toList());

     temp.removeAll(deletedItems);
     noteListAdapter.updateList(temp);

    }
Shalu T D
  • 3,373
  • 2
  • 21
  • 32
CodingFR
  • 167
  • 1
  • 10
  • You might need to use ```noteListAdapter.notifyDataSetChanged()``` to update the RecyclerView. [This answer might also help](https://stackoverflow.com/questions/35147466/set-notifydatasetchanged-on-recyclerview-adapter) – kshitij86 Jun 09 '20 at 13:38
  • @CodingFR In `delete_note()`, what is the definition of `notes`? – MelvinWM Jun 09 '20 at 13:39
  • RecyclerView is automatically updated using DiffUtils and it even seems to me that we should avoid using noteListAdapter.notifyDataSetChanged() – CodingFR Jun 09 '20 at 13:40
  • @MelvinWM notes is used to set the adapter of the recyclerView when the activity starts (it's a list that i get from the room database) – CodingFR Jun 09 '20 at 13:42
  • @CodingFR I apologize, but I cannot find `getSelectedItems`. Is it a method that you define yourself? – MelvinWM Jun 09 '20 at 13:52
  • yes, but this methods just uses the position that I get in the @onBindViewHolder – CodingFR Jun 09 '20 at 14:27

0 Answers0