Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inconsistency detected. Invalid item position 0(offset:-1)... RecyclerView crashes, on deleting first item

I am trying to delete the first item in my RecyclerView. The changes to list is monitored using livedata and diffutil. The crash happens only when the first item in RecyclerView is deleted (0th index). This might seem similar to other related questions. The issue doesn't occur while scrolling fast, etc. Ot only occurs while removing item at 0th position. The item itself is deleted from the DB. But app crashes. I tried retracing the error from the RecyclerView class: .tryGetViewHolderForPositionByDeadline(RecyclerView.java:5923)

From RecyclerView.java:

if (offsetPosition < 0 || offsetPosition >= mAdapter.getItemCount()) {
            throw new IndexOutOfBoundsException("Inconsistency detected. Invalid item "
                    + "position " + position + "(offset:" + offsetPosition + ")."
                    + "state:" + mState.getItemCount());
        }

The offset position is less than 0 (-1)

Complete error stack:

03-23 08:55:38.739 25087-25087/com.application.essentials E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.application.essentials, PID: 25087
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 0(offset:-1).state:3 android.support.v7.widget.RecyclerView{41df14f0 VFED.V.. ......ID 0,0-480,606 #7f080084 app:id/recycler_view}, adapter:com.application.essentials.model.AlarmsAdapter@41dd7d80, layout:android.support.v7.widget.LinearLayoutManager@41e10b80, context:com.application.essentials.MainActivity@41d37840
    at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5923)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
    at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
    at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557)
    at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
    at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:622)
    at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3875)
    at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3639)
    at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4194)
    at android.view.View.layout(View.java:15819)
    at android.view.ViewGroup.layout(ViewGroup.java:4884)
    at android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1183)
    at android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:870)
    at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:889)
    at android.view.View.layout(View.java:15819)
    at android.view.ViewGroup.layout(ViewGroup.java:4884)
    at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1775)
    at android.view.View.layout(View.java:15819)
    at android.view.ViewGroup.layout(ViewGroup.java:4884)
    at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:142)
    at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:41)
    at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1556)
    at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:888)
    at android.view.View.layout(View.java:15819)
    at android.view.ViewGroup.layout(ViewGroup.java:4884)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
    at android.view.View.layout(View.java:15819)
    at android.view.ViewGroup.layout(ViewGroup.java:4884)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1440)
    at android.view.View.layout(View.java:15819)
    at android.view.ViewGroup.layout(ViewGroup.java:4884)...
like image 644
Melvin Avatar asked Mar 23 '19 03:03

Melvin


1 Answers

The issue was with the Adapter. I was using setHasStableIds(true); in Adapter Constructor, to avoid "blinking of items on change". I had overrided the 2 methods: public long getItemId(int position) {...} and public int getItemViewType(int position) {...}

The crash disappeared and the 0th item was removed, once I deleted the line: setHasStableIds(true); in the constructor. But the items were blinking. The issue was with what I was returning in the overridden methods. Below code had a problem:

    @Override
public long getItemId(int position) {
     return position;
}

@Override
public int getItemViewType(int position) {
    return position;
}

The position I was returning wasn't unique. I returned the id of the item as a unique ID, and the problem disappeared.

Correct code:

    @Override
public long getItemId(int position) {
   return mAlarmEntityList.get(position).getAlarmId();
}

@Override
public int getItemViewType(int position) {
    return position;
}

I spent hours figuring out what was wrong. These answers helped me: Inconsistency detected in RecyclerView, How to change contents of RecyclerView while scrolling

How to prevent RecyclerView item from blinking after notifyItemChanged(pos)?

Hope this helps someone!

like image 91
Melvin Avatar answered Nov 19 '22 02:11

Melvin