title: Maintaining checkbox states in listview with CursorAdapter
body: <p>For my Android project, I have a listview which has a checkbox for every item. The data is loaded from an SQLite database by using a CursorAdapter class. However, whenever I scroll, the checkbox positions will get moved and get carried down to the next part of the listview. How can I fix this problem?
  <a href="https://i.stack.imgur.com/pkpL8.gif" rel="nofollow noreferrer">GIF of my CheckBox Problem</a>
  Here's my Cursor Adapter Class:</p>
  
  <pre><code>public class VocabCursorAdapter extends CursorAdapter {
  
  private static final int DIFFICULT = 0;
  private static final int FAMILIAR = 1;
  private static final int EASY = 2;
  private static final int PERFECT = 3;
  
  public VocabCursorAdapter(Context context, Cursor c, int flags) {
      super(context, c, 0);
  }
  
  @Override
  public View newView(Context context, Cursor cursor, ViewGroup parent) {
      return LayoutInflater.from(context).inflate(R.layout.item_vocab, parent, false);
  }
  
  @Override
  public void bindView(View view, Context context, Cursor cursor) {
      // Find fields to populate in inflated template
      TextView tvVocabName = (TextView) view.findViewById(R.id.vocabName);
      TextView tvVocabDefinition = (TextView) view.findViewById(R.id.vocabDefinition);
      ImageView tvVocabLevel = (ImageView) view.findViewById(R.id.vocabLevel);
      // Extract properties from cursor
      String vocab = cursor.getString(cursor.getColumnIndexOrThrow(VocabDbContract.COLUMN_NAME_VOCAB));
      String definition = cursor.getString(cursor.getColumnIndexOrThrow(VocabDbContract.COLUMN_NAME_DEFINITION));
      int level = cursor.getInt(cursor.getColumnIndexOrThrow(VocabDbContract.COLUMN_NAME_LEVEL));
      // Populate fields with extracted properties
      tvVocabName.setText(vocab);
      tvVocabDefinition.setText(definition);
  
      if (level == DIFFICULT) {
          tvVocabLevel.setImageResource(R.drawable.level_bars_difficult);
          tvVocabLevel.setTag(DIFFICULT);
      }
      else if (level == FAMILIAR) {
          tvVocabLevel.setImageResource(R.drawable.level_bars_familiar);
          tvVocabLevel.setTag(FAMILIAR);
      }
      else if (level == EASY) {
          tvVocabLevel.setImageResource(R.drawable.level_bars_easy);
          tvVocabLevel.setTag(EASY);
      }
      else if (level == PERFECT) {
          tvVocabLevel.setImageResource(R.drawable.level_bars_perfect);
          tvVocabLevel.setTag(PERFECT);
      }
  }
  </code></pre>
  
  <p>And here's my list item xml, item_vocab.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:longClickable="true"&gt;
  
  &lt;ImageView
      android:layout_width="36sp"
      android:layout_height="36sp"
      android:id="@+id/vocabLevel"
      android:layout_gravity="right"
      android:src="@drawable/level_bars"
      android:scaleType="fitXY"
      android:contentDescription="@string/vocab_level"
      android:layout_centerVertical="true"
      android:layout_toLeftOf="@+id/editCheckbox"
      android:layout_toStartOf="@+id/editCheckbox"/&gt;
  
  &lt;TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textAppearance="?android:attr/textAppearanceLarge"
      android:text="Large Text"
      android:id="@+id/vocabName"
      android:layout_alignParentTop="true"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_toLeftOf="@+id/vocabLevel"
      android:layout_toStartOf="@+id/vocabLevel"/&gt;
  
  &lt;TextView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:textAppearance="?android:attr/textAppearanceSmall"
      android:text="Small Text"
      android:id="@+id/vocabDefinition"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_toLeftOf="@+id/vocabLevel"
      android:layout_toStartOf="@+id/vocabLevel"
      android:layout_below="@id/vocabName"/&gt;
  
  &lt;CheckBox
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/editCheckbox"
      android:layout_centerVertical="true"
      android:layout_alignParentRight="true"
      android:layout_alignParentEnd="true"/&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>And here's my xml which contains a listview</p>
  
  <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              tools:context=".controller.MyVocab"
              android:paddingLeft="5dp"&gt;
  
  &lt;ListView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:id="@+id/mVocabList"
      android:layout_alignParentTop="true"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"/&gt;
  
  &lt;TextView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="@string/empty_text_view"
      android:id="@android:id/empty"
      android:layout_alignParentTop="true"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"/&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>I have looked at a lot of different solutions on StackOverflow, but I wasn't able to successfully do it in my own app. For an example, this <a href="https://stackoverflow.com/questions/4803756/android-cursoradapter-listview-and-checkbox">post</a> has a similar problem, but its solution used getView and I had trouble understanding how to implement it with newView and bindView instead.</p>
  
  <p>And some other solutions might be examples where a cursoradapter is not involved. Any help is much appreciated, thanks a lot!
  Edit #1: After incorporating Phan's changes, the checkbox states get resets to false rather than keeping its states when I scroll the listview (See <a href="https://i.stack.imgur.com/kZatK.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/kZatK.gif" alt="GIF"></a>).</p>