Levi007
Levi007

Reputation: 335

java.lang.IndexOutOfBoundsException error when using ItemTouchHelper in recyclerView?

I've read all the stackoverflows with this theme so far and the problem is not solved. I have an ItemTouchHelper :

ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
                0,
                ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT)
         {
            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull ViewHolder viewHolder, @NonNull ViewHolder target) {
                return false;
            }

        @Override
        public void onSwiped(@NonNull ViewHolder viewHolder, int direction) {
            mNotes.remove(viewHolder.getAdapterPosition());
            mAdapter.notifyItemChanged(viewHolder.getAdapterPosition());
        }
    });`enter code here`

that attached to recyclerView with this adapter :

public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.MyViewHolder> {

List<Note> notes;
Context context;
public NotesAdapter(List<Note> notes, Context context) {
    this.notes = notes;
    this.context = context;
}

public void setNotes(List<Note> notes) {
    this.notes = notes;
}

@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(context).inflate(R.layout.note_list_item, parent, false);
    return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    holder.bind(notes.get(position));
}

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

public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView title, text, date;
    Note mNote;
    public MyViewHolder(@NonNull View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        title = itemView.findViewById(R.id.note_item_title);
        text = itemView.findViewById(R.id.note_item_text);
        date = itemView.findViewById(R.id.note_item_date);
    }

    @Override
    public void onClick(View v) {
        Intent intent = NoteEditActivity.newIntent(context, mNote);
        context.startActivity(intent);
    }

    public void bind(Note note) {
        mNote = note;
        text.setText(note.getText());
        title.setText(note.getTitle());
        date.setText(note.getDate().toString());
    }
}

}

and recyclerView have LinearLayoutManager. when i tried to swipe i got this error:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{ac354a70 position=10 id=-1, oldPos=10, pLpos:-1 scrap [attachedScrap] tmpDetached no parent} androidx.recyclerview.widget.RecyclerView{aba0d698 VFED.... .F....I. 0,0-1080,1581 #7f08008b app:id/recycler_view}, adapter:com.example.notebook_v2.NotesAdapter@ac317680, layout:androidx.recyclerview.widget.LinearLayoutManager@aba66738, context:com.example.notebook_v2.NoteListActivity@ab9fd968
    at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5715)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5898)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
    at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
    at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557)
    at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
    at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3875)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3639)
    at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4194)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at androidx.drawerlayout.widget.DrawerLayout.onLayout(DrawerLayout.java:1231)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1987)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1744)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
    at android.view.Choreographer.doCallbacks(Choreographer.java:574)
    at android.view.Choreographer.doFrame(Choreographer.java:544)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
    at android.os.Handler.handleCallback(

I don't know what to do and the internet has not helped me so far.enter code here

Upvotes: 0

Views: 1650

Answers (1)

mohammad fakhraee
mohammad fakhraee

Reputation: 322

The reason you get this error is because you're calling notifyItemChanged instead of notifyItemRemoved. You are deleting an item from mNotes so your list has one item less than before. When you call notifyItemChanged, it tells the adapter that you just changed an item so nothing has removed. The adapter looks for last item to load, but there is no item there!

Try using this:

ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
            0,
            ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT)
     {
        @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull ViewHolder 
                viewHolder, @NonNull ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(@NonNull ViewHolder viewHolder, int direction) {
        mNotes.remove(viewHolder.getAdapterPosition());
        mAdapter.notifyItemRemoved(viewHolder.getAdapterPosition());
    }
});`enter code here`

Upvotes: 1

Related Questions