Search code examples
androidsimplecursoradapter

Looping over cursor not same count as cursor count on android


In my app I´m using a SimpleCursorAdapter to display contacts.

Each view has it´s own checkbox. in order to check all, I´m going through the cursor, putting each ID to a Set, which is progressed by the getView() method to trigger checkboxes.

The problem is here:

   int counter = 0;
   if (cursor.moveToFirst())
            while (cursor.moveToNext()) {
                contact_ids_to_skip.add(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)));
                counter++;

            }

The first list entry is always triggered, because counter is 157, and cursor.getCount() is 158.

I do not know what is happening here. I thought cursor.moveToFirst() is putting the cursor into its right position, but thats not the case.

How can I solve this?

Edit: I read the contact id from the first view which wont get unchecked at any point, and it is not getting added to the set in the upper code


Solution

  • Look at your logic. First, you move to the first record. Immediately after that, you moveToNext(). The first item is being skipped.

    A few options:

    Move the moveToNext() call to the end of the loop:

       int counter = 0;
       if (cursor.moveToFirst())
                do {
                    contact_ids_to_skip.add(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)));
                    counter++;
                } while(cursor.moveToNext())
    

    Change moveToFirst() to moveToPosition(-1):

       int counter = 0;
       if (cursor.moveToPosition(-1))
                while (cursor.moveToNext()) {
                    contact_ids_to_skip.add(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)));
                    counter++;
                }
    

    Or, simply get rid of moveToFirst() altogether:

       int counter = 0;
       while (cursor.moveToNext()) {
           contact_ids_to_skip.add(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)));
           counter++;
       }
    

    The last works because when a Cursor is returned from any query method, it's position is -1, which is "before the first item". So, a moveToNext() puts it in the right spot. Only use that one if the Cursor has just been returned from a query, though. If its position has been changed, use one of the first two methods.