title: Recycler View: Inconsistency detected. Invalid view holder adapter positionViewHolder
body: <p>Recycler View Inconsistency Detected error, coming while scrolling fast or scrolling while loading more items..</p>
  
  <pre><code>FATAL EXCEPTION: main
  Process: com.pratap.endlessrecyclerview, PID: 21997
  java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{56a082c position=40 id=-1, oldPos=39, pLpos:39 scrap [attachedScrap] tmpDetached no parent}
  at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:4251)
  at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4382)
  at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4363)
  at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1961)
  at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1370)
  at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1333)
  at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:562)
  at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2864)
  at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1445)
  at android.support.v7.widget.RecyclerView.access$400(RecyclerView.java:144)
  at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:282)
  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
  at android.view.Choreographer.doCallbacks(Choreographer.java:670)
  at android.view.Choreographer.doFrame(Choreographer.java:603)
  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
  at android.os.Handler.handleCallback(Handler.java:746)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:148)
  at android.app.ActivityThread.main(ActivityThread.java:5443)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
  </code></pre>
  
  <p><strong>Adapter</strong></p>
  
  <pre><code>public class DataAdapter extends RecyclerView.Adapter {
      private final int VIEW_ITEM = 1;
      private final int VIEW_PROG = 0;
  
      private List&lt;Feed&gt; mFeed;
      // The minimum amount of items to have below your current scroll position
      // before loading more.
      private int visibleThreshold = 5;
      private int lastVisibleItem, totalItemCount;
      private boolean loading;
      private OnLoadMoreListener onLoadMoreListener;
  
      public DataAdapter(List&lt;Feed&gt; feeds, RecyclerView recyclerView) {
  
          mFeed = feeds;
  
          if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
  
              final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView
                  .getLayoutManager();
  
              recyclerView
                  .addOnScrollListener(new RecyclerView.OnScrollListener() {
                      @Override
                      public void onScrolled(RecyclerView recyclerView,
                          int dx, int dy) {
                          super.onScrolled(recyclerView, dx, dy);
  
                          totalItemCount = linearLayoutManager.getItemCount();
                          lastVisibleItem = linearLayoutManager
                              .findLastVisibleItemPosition();
                          if (!loading
                              &amp;&amp; totalItemCount &lt;= (lastVisibleItem + visibleThreshold)) {
                              // End has been reached
                              // Do something
                              if (onLoadMoreListener != null) {
                                  onLoadMoreListener.onLoadMore();
                              }
                              loading = true;
                          }
                      }
                  });
          }
      }
  
      @Override
      public int getItemViewType(int position) {
          return mFeed.get(position) == null ? VIEW_PROG : VIEW_ITEM;
      }
  
      @Override
      public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
          int viewType) {
          RecyclerView.ViewHolder vh;
          if (viewType == VIEW_ITEM) {
              View v = LayoutInflater.from(parent.getContext()).inflate(
                  R.layout.list_row, parent, false);
  
              vh = new StudentViewHolder(v);
          }
          else {
              View v = LayoutInflater.from(parent.getContext()).inflate(
                  R.layout.progress_item, parent, false);
  
              vh = new ProgressViewHolder(v);
          }
          return vh;
      }
  
      @Override
      public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
          if (holder instanceof StudentViewHolder) {
  
              Feed singleStudent= (Feed) mFeed.get(position);
              ((StudentViewHolder) holder).tvName.setText(singleStudent.getTitle());
              ((StudentViewHolder) holder).student= singleStudent;
          } else {
              ProgressViewHolder.PROGRESS_BAR.setIndeterminate(true);
          }
      }
  
      public void setLoaded() {
          loading = false;
      }
  
      public void  addFeed(Feed feed) {
          mFeed.add(feed);
          //mFeed.addAll(0, (Collection&lt;? extends Feed&gt;) feed);
          notifyItemInserted(mFeed.size());
          //notifyItemRangeInserted(0,mFeed.size());
          notifyDataSetChanged();
          //notifyItemInserted(mFeed.size());
          //setLoaded();
          //notifyItemInserted(mFeed.size());
      }
  
      public void removeAll(){
          mFeed.clear();
          notifyDataSetChanged();
      }
  
      @Override
      public int getItemCount() {
          return mFeed.size();
      }
  
      public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
          this.onLoadMoreListener = onLoadMoreListener;
      }
  
      public static class StudentViewHolder extends RecyclerView.ViewHolder {
          public TextView tvName;
  
          public Feed student;
          public StudentViewHolder(View v) {
              super(v);
              tvName = (TextView) v.findViewById(R.id.tvName);
  
              //tvEmailId = (TextView) v.findViewById(R.id.tvEmailId);
          }
      }
  
      public static class ProgressViewHolder extends RecyclerView.ViewHolder {
          //public ProgressBar progressBar;
          public static ProgressBar PROGRESS_BAR;
          public ProgressViewHolder(View v) {
              super(v);
              PROGRESS_BAR = (ProgressBar) v.findViewById(R.id.progressBar1);
              //  progressBar = (ProgressBar) v.findViewById(R.id.progressBar1);
          }
      }
  }
  </code></pre>
  
  <p><strong>Activity</strong></p>
  
  <pre><code>public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {
  
      private Toolbar toolbar;
  
      private TextView tvEmptyView;
      private RecyclerView mRecyclerView;
      private DataAdapter mAdapter;
      private LinearLayoutManager mLayoutManager;
      private RestManager mManager;
      private List&lt;Feed&gt; mFeed;
      SwipeRefreshLayout mSwipeRefreshLayout;
      protected Handler handler;
      private int currentPage=1;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          toolbar = (Toolbar) findViewById(R.id.toolbar);
          tvEmptyView = (TextView) findViewById(R.id.empty_view);
          mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
          mSwipeRefreshLayout= (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
          mSwipeRefreshLayout.setOnRefreshListener(this);
          //studentList = new ArrayList&lt;Student&gt;();
          mFeed = new ArrayList&lt;Feed&gt;();
          handler = new Handler();
          if (toolbar != null) {
              setSupportActionBar(toolbar);
              getSupportActionBar().setTitle("Android Students");
  
          }
          mManager = new RestManager();
  
          // use this setting to improve performance if you know that changes
          // in content do not change the layout size of the RecyclerView
          mRecyclerView.setHasFixedSize(true);
  
          mLayoutManager = new LinearLayoutManager(this);
  
          // use a linear layout manager
          mRecyclerView.setLayoutManager(mLayoutManager);
  
          // create an Object for Adapter
          mAdapter = new DataAdapter(mFeed,mRecyclerView);
  
          // set the adapter object to the Recyclerview
          mRecyclerView.setAdapter(mAdapter);
          //   mAdapter.notifyDataSetChanged();
  
          loadData(false);
  
          //        if (mFeed.isEmpty()) {
          //            mRecyclerView.setVisibility(View.GONE);
          //            tvEmptyView.setVisibility(View.VISIBLE);
          //
          //        } else {
          //            mRecyclerView.setVisibility(View.VISIBLE);
          //            tvEmptyView.setVisibility(View.GONE);
          //        }
  
          mAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
              @Override
              public void onLoadMore() {
                  //add null , so the adapter will check view_type and show progress bar at bottom
                  mFeed.add(null);
                  mAdapter.notifyItemInserted(mFeed.size() - 1);
  
                  handler.postDelayed(new Runnable() {
                      @Override
                      public void run() {
                          //   remove progress item
                          mFeed.remove(mFeed.size() - 1);
                          // mAdapter.notifyItemRemoved(mFeed.size());
                          //add items one by one
                          int start = mFeed.size();
                          currentPage++;
  
                          Log.d("CurrentPage", String.valueOf(currentPage));
                          Call&lt;Results&gt; listCall = mManager.getFeedApi().getAllFeeds(1);
  
                          listCall.enqueue(new Callback&lt;Results&gt;() {
  
                              @Override
                              public void onResponse(Call&lt;Results&gt; call, Response&lt;Results&gt; response) {
                                  mSwipeRefreshLayout.setRefreshing(false);
                                  if (response.isSuccess()) {
                                      if (response.body() != null) {
                                          Results feedList = response.body();
  
                                          // List&lt;Results&gt; newUsers = response.body();
  
                                          Log.d("Retrofut", String.valueOf(feedList));
  
                                          for (int i = 0; i &lt; feedList.results.size(); i++) {
                                              Feed feed = feedList.results.get(i);
                                              // mFeed.add(feed);
                                              mAdapter.addFeed(feed);
                                              //                                        mAdapter.notifyDataSetChanged();
  
  
                                              //mAdapter.notifyItemInserted(mFeed.size());
  
                                          }
                                          //    mAdapter.notifyDataSetChanged();
                                      }
                                  }
                              }
  
                              @Override
                              public void onFailure(Call&lt;Results&gt; call, Throwable t) {
                                  Log.d("Retrofut", "Error");
                                  mFeed.remove(mFeed.size() - 1);
                                  mAdapter.notifyItemRemoved(mFeed.size());
  
                                  mAdapter.setLoaded();
                                  mSwipeRefreshLayout.setRefreshing(false);
                              }
                          });
  
                          //        for (int i = 1; i &lt;= 20; i++) {
                          //            studentList.add(new Student("Student " + i, "androidstudent" + i + "@gmail.com"));
                          //
                          //        }
  
                          mAdapter.setLoaded();
                          //or you can add all at once but do not forget to call mAdapter.notifyDataSetChanged();
  
                      }
                  }, 2000);
              }
          });
      }
  
      // load initial data
      private void loadData(final boolean removePreData) {
  
          Call&lt;Results&gt; listCall = mManager.getFeedApi().getAllFeeds(1);
  
          listCall.enqueue(new Callback&lt;Results&gt;() {
  
                               @Override
                               public void onResponse(Call&lt;Results&gt; call, Response&lt;Results&gt; response) {
  
                                   if (response.isSuccess()) {
                                       if (response.body() != null) {
                                           //  if(removePreData) mAdapter.removeAll();
                                           Results feedList = response.body();
                                           Log.d("Retrofut", String.valueOf(feedList));
  
                                           for (int i = 0; i &lt; feedList.results.size(); i++) {
                                               Feed feed = feedList.results.get(i);
                                               // mFeed.add(feed);
                                               //mAdapter.notifyDataSetChanged();
                                               mAdapter.addFeed(feed);
                                           }
  
                                           mSwipeRefreshLayout.setRefreshing(false);
                                       }
                                   }
                               }
  
                               @Override
                               public void onFailure(Call&lt;Results&gt; call, Throwable t) {
                                   Log.d("Retrofut", String.valueOf(t));
                                   mFeed.remove(mFeed.size() - 1);
                                   mAdapter.notifyItemRemoved(mFeed.size());
                                   mAdapter.setLoaded();
                                   mSwipeRefreshLayout.setRefreshing(false);
                               }
                           }
          );
  
          //        for (int i = 1; i &lt;= 20; i++) {
          //            studentList.add(new Student("Student " + i, "androidstudent" + i + "@gmail.com"));
          //
          //        }
  
          mSwipeRefreshLayout.setRefreshing(true);
      }
  
      @Override
      public void onRefresh() {
          mFeed.clear();
          mAdapter.notifyDataSetChanged();
          loadData(true);
          currentPage=1;
      }
  }
  </code></pre>