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);
}