title: RecyclerView java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter position. Due to changing getItemCount()
body: <p>I am getting a <code>java.lang.IndexOutOfBoundsException: Inconsistency detected</code> with the <code>RecyclerView</code>, but only when I seem to fling it. When I scroll slow enough it doesn't crash on me.</p>
  
  <p>I use my base adapter for many other subclasses but only certain ones crash on me. Any idea why this is happening?</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>I figured out the reason this is happening is because <code>getItemCount()</code> changes depending on the status of my footer loading views. I believe this is causing an inconsistency when it changes and while I am scrolling.</p>
  
  <p>I tested this by always returning 2 extra items for my header/footer loading views in getItemCount(). Instead of dynamically calculating the count based on their statuses. What would be a good approach to fixing this issue?</p>
  
  <p><strong>My adapter</strong> </p>
  
  <pre><code>public abstract class BaseRecyclerAdapter&lt;T&gt;
          extends RecyclerView.Adapter&lt;RecyclerView.ViewHolder&gt;
          implements LoadingAndErrorViewHolder.LoadingViewHolderListener {
  
      public static final int STATUS_HIDDEN = 0;
      public static final int STATUS_LOADING = 1;
      public static final int STATUS_ERROR = 2;
  
      protected static final int TYPE_HEADER_LOADING = 0;
      protected static final int TYPE_FOOTER_LOADING = 1;
      protected static final int TYPE_NORMAL = 2;
  
      private static final int POSITION_TYPE_HEADER_LOADING = 0;
  
      private BaseRecyclerAdapterListener mBaseRecyclerAdapterListener;
      private final List&lt;T&gt; mBackingList = new ArrayList&lt;T&gt;();
      private int mHeaderStatus = STATUS_HIDDEN;
      private int mFooterStatus = STATUS_HIDDEN;
      private final int mNumOfHeaderItems;
  
      public interface BaseRecyclerAdapterListener {
          void onErrorHeaderRetryClicked();
          void onErrorFooterRetryClicked();
      }
  
      public BaseRecyclerAdapter() {
          this(null);
      }
  
      public BaseRecyclerAdapter(BaseRecyclerAdapterListener listener) {
          this(0, listener);
      }
  
      public BaseRecyclerAdapter(int numOfHeaderItems, BaseRecyclerAdapterListener listener) {
          mNumOfHeaderItems = numOfHeaderItems;
          mBaseRecyclerAdapterListener = listener;
          setHasStableIds(true);
      }
  
      @Override
      public long getItemId(int position) {
          final T item = getItem(position);
          if (item != null) {
              return item.hashCode();
          } else {
              return position;
          }
      }
  
      @Override
      public int getItemCount() {
          int count = mBackingList.size();
          if (mHeaderStatus != STATUS_HIDDEN) {
              count++;
          }
          if (mFooterStatus != STATUS_HIDDEN) {
              count++;
          }
          return mNumOfHeaderItems + count;
      }
  
      @Override
      public int getItemViewType(int position) {
          final int headerAdjustment = mHeaderStatus != STATUS_HIDDEN ? 1 : 0;
          if (position == 0 &amp;&amp; mHeaderStatus != STATUS_HIDDEN) {
              return TYPE_HEADER_LOADING;
          } else if (position &lt; mBackingList.size() + headerAdjustment + mNumOfHeaderItems) {
              return TYPE_NORMAL;
          } else {
              return TYPE_FOOTER_LOADING;
          }
      }
  
      @Override
      public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
          switch (viewType) {
              case TYPE_HEADER_LOADING: {
                  return new LoadingAndErrorViewHolder(inflater.inflate(
                          LoadingAndErrorViewHolder.LAYOUT_ID, parent, false),
                          LoadingAndErrorViewHolder.TYPE_HEADER, this);
              }
              case TYPE_FOOTER_LOADING: {
                  return new LoadingAndErrorViewHolder(inflater.inflate(
                          LoadingAndErrorViewHolder.LAYOUT_ID, parent, false),
                          LoadingAndErrorViewHolder.TYPE_FOOTER, this);
              }
              default: {
                  return onCreateItemViewHolder(parent, viewType);
              }
          }
      }
  
      @Override
      public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
          final int viewType = getItemViewType(position);
          switch (viewType) {
              case TYPE_HEADER_LOADING: {
                  ((LoadingAndErrorViewHolder) holder).setStatus(mHeaderStatus);
                  break;
              }
              case TYPE_FOOTER_LOADING: {
                  ((LoadingAndErrorViewHolder) holder).setStatus(mFooterStatus);
                  break;
              }
              default: {
                  onBindItemViewHolder(holder, position);
              }
          }
      }
  
      @Override
      public void onHeaderLoadingViewHolderClick() {
          if (mBaseRecyclerAdapterListener != null) {
              mBaseRecyclerAdapterListener.onErrorHeaderRetryClicked();
          }
      }
  
      @Override
      public void onFooterLoadingViewHolderClick() {
          if (mBaseRecyclerAdapterListener != null) {
              mBaseRecyclerAdapterListener.onErrorFooterRetryClicked();
          }
      }
  
      public T getItem(int position) {
          final int headerAdjustment = mHeaderStatus != STATUS_HIDDEN ? 1 : 0;
          final int adjustedPosition = position - headerAdjustment - mNumOfHeaderItems;
          if (adjustedPosition &lt; 0
                  || (mFooterStatus != STATUS_HIDDEN &amp;&amp; position == getItemCount() - 1)) {
              return null;
          } else {
              return mBackingList.get(adjustedPosition);
          }
      }
  
      public List&lt;T&gt; getList() {
          return mBackingList;
      }
  
      public int getListSize() {
          return mBackingList.size();
      }
  
      public void setList(List&lt;T&gt; list) {
          if (list != null) {
              clear();
              add(list);
          }
      }
  
      public void add(T item) {
          if (item != null) {
              mBackingList.add(item);
              notifyItemInserted(getItemCount() - 1);
          }
      }
  
      public void add(int index, T item) {
          if (item != null) {
              mBackingList.add(index, item);
              notifyItemInserted(index + getItemOffset());
          }
      }
  
      public void add(List&lt;T&gt; list) {
          if (list != null) {
              final int currentLastIndex;
              if (mBackingList.size() &gt; 0) {
                  currentLastIndex = mBackingList.size() - 1;
              } else {
                  currentLastIndex = 0;
              }
              mBackingList.addAll(list);
              notifyItemRangeInserted(currentLastIndex + getItemOffset(), list.size());
          }
      }
  
      public void add(int index, List&lt;T&gt; list) {
          if (list != null) {
              mBackingList.addAll(index, list);
              notifyItemRangeInserted(index + getItemOffset(), list.size());
          }
      }
  
      public void update(int position, T item) {
          mBackingList.set(position, item);
          notifyItemChanged(position + getItemOffset());
      }
  
      public void remove(T item) {
          if (item != null &amp;&amp; mBackingList.remove(item)) {
              notifyDataSetChanged();
          }
      }
  
      public void clear() {
          mBackingList.clear();
          notifyDataSetChanged();
      }
  
      public void setHeaderStatus(int headerStatus) {
          mHeaderStatus = headerStatus;
          notifyItemChanged(POSITION_TYPE_HEADER_LOADING);
      }
  
      public void setFooterStatus(int footerStatus) {
          mFooterStatus = footerStatus;
          notifyItemChanged(getItemCount() - 1);
      }
  
      public void checkEndOfList(List&lt;T&gt; data) {
          if (data.isEmpty()) {
              setFooterStatus(STATUS_HIDDEN);
          } else {
              setFooterStatus(STATUS_LOADING);
          }
      }
  
      protected int getHeaderStatus() {
          return mHeaderStatus;
      }
  
      protected int getFooterStatus() {
          return mFooterStatus;
      }
  
      protected abstract RecyclerView.ViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType);
  
      protected abstract void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position);
  
      private int getItemOffset() {
          final int headerAdjustment = mHeaderStatus != STATUS_HIDDEN ? 1 : 0;
          return headerAdjustment + mNumOfHeaderItems;
      }
  }
  </code></pre>
  
  <p><strong>Stacktrace</strong></p>
  
  <pre><code>06-01 10:46:36.230 11448-11448/com.fusionprojects.edmodo E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: com.fusionprojects.edmodo, PID: 11448
                                                                             java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{dcf5c3a position=23 id=-1, oldPos=23, pLpos:-1 scrap [attachedScrap] tmpDetached no parent}
                                                                                 at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5297)
                                                                                 at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5479)
                                                                                 at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5440)
                                                                                 at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5436)
                                                                                 at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2224)
                                                                                 at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1551)
                                                                                 at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1511)
                                                                                 at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:595)
                                                                                 at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3534)
                                                                                 at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3310)
                                                                                 at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3844)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:636)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                 at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1795)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
                                                                                 at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
                                                                                 at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                 at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                 at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
                                                                                 at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
                                                                                 at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                 at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
                                                                                 at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
                                                                                 at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                 at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
                                                                                 at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
  06-01 10:46:36.231 11448-11448/com.fusionprojects.edmodo E/AndroidRuntime:     at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                 at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                 at com.android.internal.policy.DecorView.onLayout(DecorView.java:726)
                                                                                 at android.view.View.layout(View.java:17641)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                 at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2346)
                                                                                 at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2068)
                                                                                 at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
                                                                                 at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6343)
                                                                                 at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
                                                                                 at android.view.Choreographer.doCallbacks(Choreographer.java:686)
                                                                                 at android.view.Choreographer.doFrame(Choreographer.java:621)
                                                                                 at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
                                                                                 at android.os.Handler.handleCallback(Handler.java:751)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                 at android.os.Looper.loop(Looper.java:154)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:6126)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
  </code></pre>