Search code examples
javaandroidcursorandroid-contentproviderandroid-cursorloader

CursorLoader, unsubscribe from ContentProvider notifications


I'm using a CursorLoader to query a ContentProvider to populate a ListView, with the following code (wrapped in a LoaderManager):

CursorLoader loader = new CursorLoader(getActivity(),
                Provider.CONTENT_SOME_URI,
                projection,
                selection,
                null,
                null);

And an AsyncQueryHandler to update SOME_VALUE for a given _id triggered on click on a CheckBox placed on every single entry of the ListView

final AsyncQueryHandler handler = new AsyncQueryHandler(contentResolver) {};
final ContentValues values = new ContentValues();
                    values.put(Table.SOME_COLUMN, someValue);
final Uri uri = Uri.withAppendedPath(Provider.CONTENT_SOME_URI, String.valueOf(someId));
handler.startUpdate(0,
       null,
       uri,
       values,
       null,
       null);

Finally, in my ContentProvider, I've something like that:

@Override
public int update(Uri uri, ...){
    ... // update stuff
    getContext().getContentResolver().notifyChange(uri, null);
}

The problem is the following:

When I check a single item, this item is updated, notifyChange tells CursorLoader to reload, and the whole list is reloaded, causing the list to scroll top, animations to stop, each time a CheckBox is checked...

Don't know what to do...

Thanks!


Solution

  • When you call setListAdapter, that causes the list to completely wipe out its data and regenerate the whole list. You should instead only call swapCursor() in your onLoadFinished() - this tells the adapter that the data has changed, but it will use the list element ids to reuse items, causing your list to remain, in your case, completely stable