I\'m using RecyclerView
to display name of the items. My row contains single TextView
. Item names are stored in List
I had a similar issue but with deleting the contents. I also wanted to keep the animations too. I ended up using the notifyRemove, then passing the range. This seems to fix any issues...
public void deleteItem(int index) {
try{
mDataset.remove(index);
notifyItemRemoved(index);
} catch (IndexOutOfBoundsException e){
notifyDataSetChanged();
e.printStackTrace();
}
}
Seems to be working and getting rid of the IOB Exception...
create CustomLinearLayoutManager:
public class CustomLinearLayoutManager extends LinearLayoutManager {
public CustomLinearLayoutManager(Context context) {
super(context);
}
public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public CustomLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public boolean supportsPredictiveItemAnimations() {
return false;
}
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}
}
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
return super.scrollVerticallyBy(dy, recycler, state);
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
I also had the same issue and I have fixed it with not using notifyItemRangeChanged() method. It is nicely explained at
https://code.google.com/p/android/issues/detail?id=77846#c10
The problem is definitely not because of recyclerview scrolling, but it is related to notifyDataSetChanged(). I had a recycler view in which i was constantly changing data i.e. adding and removing data. I was calling notifyDataSetChanged() everytime I was adding items to my list, But was not refreshing the adapter whenever the item is being removed or the list was cleared.
So to fix the :
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 2(offset:2).state:12 at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5456)
I called adapter.notifyDataSetChanged() after list.clear(), wherever it was required.
if (!myList.isEmpty()) {
myList.clear();
myListAdapter.notifyDataSetChanged();
}
Since then, I never encountered the exception. Hope it works out the same for others as well. :)
You must use in your getitem count
public int getItemCount() {
if (mList!= null)
return mList.size();
else
return 0;
}
Also refreshing the recycler view please use this
if (recyclerView.getAdapter() == null) {
recyclerView.setHasFixedSize(true);
mFileListAdapter= new FileListAdapter(this);
recyclerView.setAdapter(mFileListAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
} else {
mFileListAdapter.notifyDataSetChanged();
}
By using this solution you are not able to solve the issue you simply use a condition inside the onBindViewHolder to resolve the java.lang.IndexOutOfBoundsException
public void onBindViewHolder(FileHolder fileHolder, final int i) {
if(i < mList.size)
{
String name = mList.get(i);
setSelected(fileHolder.itemView, mSelectedArray.get(i));
fileHolder.mTextView.setText(name);
}
}
I have replicated this issue. This happened when we remove items in the background thread from mList but dont call notifyDataSetChanged(). Now If we scroll This exception is comming.
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 86(offset:86).state:100
Initially I had 100 items and removed few items from background thread.
Seems like Recyclerview calls getItemCount() itself to validate the state.