title: RecyclerView with SQLite data crashes due to incorrect index
body: <p>I have a recyclerView which populates with data from an SQLite database. Each item has a button which can remove its flag in the database and thus disappear from the recyclerView list.</p>
  
  <p>The problem I get is when I try to remove items in different orders, the app crashes and cites an incorrect/unknown index as the cause.</p>
  
  <p>Here is the (partial) code for my recyclerView where I think the problem lies:</p>
  
  <pre><code>@Override
      public BookmarksDetailRecycleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                                         int viewType) {
          // create a new view
          View itemLayoutView = LayoutInflater.from(parent.getContext())
                  .inflate(R.layout.dua_detail_item_card, null);
  
          // create ViewHolder
          mHolder = new ViewHolder(itemLayoutView);
          return mHolder;
      }
  
      public void deleteRow(int position){
          mDuaData.remove(position); // this will remove row of data
          notifyItemRemoved(position); // this will do the animation of removal
          notifyItemRangeChanged(position, mDuaData.size()); // From GreenTech email
          // dataSetChanged();
      }
  
      @UiThread
      protected void dataSetChanged() {
          notifyDataSetChanged();
      }
  
      // Replace the contents of a view (invoked by the layout manager)
      @Override
      public void onBindViewHolder(ViewHolder mHolder, int position){//final RecyclerView rv) {
          // - get data from your itemsData at this position
          // - replace the contents of the view with that itemsData
          final int finalPosition = position;
  
          mHolder.tvDuaNumber.setText(mDuaData.get(position).getReference() + "");
          mHolder.tvDuaArabic.setText(Html.fromHtml(mDuaData.get(position).getArabic()));
  
          final Spannable translation = new SpannableString(mDuaData.get(position).getTranslation());
          mHolder.tvDuaTranslation.setText(translation);
  
          if (mDuaData.get(position).getBook_reference() != null)
              mHolder.tvDuaReference.setText(Html.fromHtml(mDuaData.get(position).getBook_reference()));
          else
              mHolder.tvDuaReference.setText("null");
  
          if (mDuaData.get(position).getFav()) {
              mHolder.favButton.setText("{faw-star}");
          } else {
              mHolder.favButton.setText("{faw-star-o}");
          }
  
          final ViewHolder finalmHolder = mHolder;
  
          mHolder.shareButton.setOnClickListener(new View.OnClickListener() {
              public void onClick(View convertView) {
                  Intent intent = new Intent();
                  intent.setAction(Intent.ACTION_SEND);
                  intent.putExtra(Intent.EXTRA_TEXT,
                          myToolbarTitle + "\n\n" +
                                  finalmHolder.tvDuaArabic.getText() + "\n\n" +
                                  finalmHolder.tvDuaTranslation.getText() + "\n\n" +
                                  finalmHolder.tvDuaReference.getText() + "\n\n" +
                                  convertView.getResources().getString(R.string.action_share_credit)
                  );
                  intent.setType("text/plain");
                  convertView.getContext().startActivity(
                          Intent.createChooser(
                                  intent,
                                  convertView.getResources().getString(R.string.action_share_title)
                          )
                  );
              }
          });
  
          finalmHolder.favButton.setOnClickListener(new View.OnClickListener() {
              public void onClick(View v) {
                  boolean isFav = false;
                  Log.d("K12_isFav", "isFav: " + isFav);
  
                  int sql_position = Integer.parseInt(finalmHolder.tvDuaNumber.getText().toString());                
  
                  Log.d("K12_sqlPosition", sql_position + "");
  
                  deleteRow(finalPosition);
  
                  Resources resources = v.getResources();
                  String snack_begin = resources.getString(R.string.snackbar_text_begin);
                  String snack_end = resources.getString(R.string.snackbar_text_end);
                  String snack_action = resources.getString(R.string.snackbar_action).toUpperCase();
  
                  // Following snippet taken from:
                  // http://developer.android.com/training/basics/data-storage/databases.html#UpdateDbRow
                  mDbHelper = new ExternalDbOpenHelper(v.getContext().getApplicationContext());
  
                  SQLiteDatabase db = mDbHelper.getReadableDatabase();
  
                  // New value for one column
                  ContentValues values = new ContentValues();
                  values.put(HisnDatabaseInfo.DuaTable.FAV, isFav);
  
                  // Which row to update, based on the ID
                  String selection = HisnDatabaseInfo.DuaTable.DUA_ID + " LIKE ?";
                  String[] selectionArgs = {String.valueOf(finalmHolder.tvDuaNumber.getText().toString())};
                  Log.d("K12_selectionArgs", "tvDuaNumber: " + String.valueOf(finalmHolder.tvDuaNumber.getText().toString()));
  
                  int count = db.update(
                          HisnDatabaseInfo.DuaTable.TABLE_NAME,
                          values,
                          selection,
                          selectionArgs);
  
                  if (count == 1) {
                      if (isFav) {
                          finalmHolder.favButton.setText("{faw-star}");
                      } else {
                          finalmHolder.favButton.setText("{faw-star-o}");                    
                      }                    
                  }
                  if (getItemCount() == 0) {
                      // I don't even know if this block is needed. Review once you have some sleep.
                  }
              }
          });
      }
  
      // inner class to hold a reference to each item of RecyclerView
      public static class ViewHolder extends RecyclerView.ViewHolder {
          public TextView tvDuaNumber;
          public TextView tvDuaArabic;
          public TextView tvDuaTranslation;
          public TextView tvDuaReference;
          public IconicsButton shareButton;
          public IconicsButton favButton;
  
          public ViewHolder(View itemLayoutView) {
              super(itemLayoutView);
              tvDuaNumber = (TextView) itemLayoutView.findViewById(R.id.txtDuaNumber);
              tvDuaArabic = (TextView) itemLayoutView.findViewById(R.id.txtDuaArabic);
              tvDuaTranslation = (TextView) itemLayoutView.findViewById(R.id.txtDuaTranslation);
              tvDuaReference = (TextView) itemLayoutView.findViewById(R.id.txtDuaReference);
              shareButton = (IconicsButton) itemLayoutView.findViewById(R.id.button_share);
              favButton = (IconicsButton) itemLayoutView.findViewById(R.id.button_star);
  
              tvDuaArabic.setTypeface(sCachedTypeface);
              tvDuaArabic.setTextSize(prefArabicFontSize);
              tvDuaTranslation.setTextSize(prefOtherFontSize);
              tvDuaReference.setTextSize(prefOtherFontSize);
          }
      }
  
      // Return the size of your itemsData (invoked by the layout manager)
      @Override
      public int getItemCount() {
          return mDuaData == null ? 0 : mDuaData.size();
      }
  </code></pre>
  
  <p>The full code for the adapter can be viewed on <a href="https://github.com/khalid-hussain/HisnulMuslim/blob/master/app/src/main/java/com/khalid/hisnulmuslim/adapter/BookmarksDetailRecycleAdapter.java" rel="nofollow">Github</a>.</p>
  
  <p>Here is the logcat report of the error:</p>
  
  <pre><code>12-06 12:01:08.288 7104-7135/com.khalid.hisnulmuslim D/OpenGLRenderer: endAllStagingAnimators on 0x67b72220 (RippleDrawable) with handle 0x67b3ad40
  12-06 12:01:08.288 7104-7135/com.khalid.hisnulmuslim D/OpenGLRenderer: endAllStagingAnimators on 0x7e596df8 (ListView) with handle 0x67b3ad28
  12-06 12:01:08.308 7104-7104/com.khalid.hisnulmuslim I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@10886dfe time:55529721
  12-06 12:01:10.968 7104-7104/com.khalid.hisnulmuslim D/K12_isFav: isFav: false
  12-06 12:01:10.968 7104-7104/com.khalid.hisnulmuslim D/K12_sqlPosition: 3
  12-06 12:01:10.978 7104-7104/com.khalid.hisnulmuslim D/K12_selectionArgs: tvDuaNumber: 3
  12-06 12:01:12.573 7104-7104/com.khalid.hisnulmuslim D/K12_isFav: isFav: false
  12-06 12:01:12.573 7104-7104/com.khalid.hisnulmuslim D/K12_sqlPosition: 1
  12-06 12:01:12.583 7104-7104/com.khalid.hisnulmuslim D/K12_selectionArgs: tvDuaNumber: 1
  12-06 12:01:14.228 7104-7104/com.khalid.hisnulmuslim D/K12_isFav: isFav: false
  12-06 12:01:14.228 7104-7104/com.khalid.hisnulmuslim D/K12_sqlPosition: 4
  12-06 12:01:14.228 7104-7104/com.khalid.hisnulmuslim D/AndroidRuntime: Shutting down VM
  12-06 12:01:14.233 7104-7104/com.khalid.hisnulmuslim E/AndroidRuntime: FATAL EXCEPTION: main
                                                                         Process: com.khalid.hisnulmuslim, PID: 7104
                                                                         java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
                                                                             at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
                                                                             at java.util.ArrayList.remove(ArrayList.java:403)
                                                                             at com.khalid.hisnulmuslim.adapter.BookmarksDetailRecycleAdapter.deleteRow(BookmarksDetailRecycleAdapter.java:90)
                                                                             at com.khalid.hisnulmuslim.adapter.BookmarksDetailRecycleAdapter$2.onClick(BookmarksDetailRecycleAdapter.java:160)
                                                                             at android.view.View.performClick(View.java:4789)
                                                                             at android.view.View$PerformClick.run(View.java:19881)
                                                                             at android.os.Handler.handleCallback(Handler.java:739)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                             at android.os.Looper.loop(Looper.java:135)
                                                                             at android.app.ActivityThread.main(ActivityThread.java:5294)
                                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                                             at java.lang.reflect.Method.invoke(Method.java:372)
                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
                                                                             at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:114)
  </code></pre>
  
  <p>I have been trying to solve this for a while but I can't really see what the problem is. Will appreciate any help.</p>
  
  <p>Thanks.</p>