9

My problem: My ListView resets its scroll position to the top whenever I update its contents through its (customized) SimpleCursorAdapter. I would like the ListView to maintain its scroll position when updated.

I started out by creating a new adapter instance every time and using ListView.setAdapter(), but according to this discussion I should be updating the adapter instead of resetting it. I can't find a way to do this for SimpleCursorAdapter that works correctly.

Here are some things I've tried, omitting the method arguments:
- SimpleCursorAdapter.changeCursorAndColumns() with a fresh cursor successfully updates the adapter but still resets the scroll position.
- SimpleCursorAdapter.changeCursor() acts the same way.
- SimpleCursorAdapter.swapCursor() isn't available until api 11, and I am developing for api 8.
- SimpleCursorAdapter.notifyDataSetChanged() does not update the ListView. (Maybe there is another step I'm missing.)
- ListView.invalidate() does not update the ListView.
- SimpleCursorAdapter.requery() makes the ListView blank, and is deprecated.
- I'm familiar with the ListView.setSelection() solution, but I don't want my ListView to move at all when it is updated. This snaps it to a position in the list.

This seems like it should be a common and simple problem. Has anybody dealt with it?

pvans
  • 1,017
  • 2
  • 10
  • 15
  • See my comment below the answer. SimpleCursorAdapter.changeCursor() does work correctly - I just had another line of code screwing things up. – pvans Feb 27 '12 at 04:13

2 Answers2

5

I've had a similar problem: My CursorAdapter reset the scroll position whenever the contents of the cursor changed.

I didn't realize that I actually did set a new list adapter each time the data changed. I thought the cursor himself would notify the adapter about changes to it's content but in my case it is the ContentProvider that triggers LoaderManager.LoaderCallbacks.onLoadFinished() in my ListFragment. In that callback I now use CursorAdapter.changeCursor() instead of creating a new adapter and everything works just fine.

I hope this helps solving your problem.

Oderik
  • 2,242
  • 2
  • 16
  • 25
  • It turns out that SimpleCursorAdapter.changeCursor() works correctly. The culprit in my case causing the listview scroll position to reset was a pair of lines of code called right before changing the cursor: `ListView.SetDivider()` and `ListView.SetDividerHeight`. Really annoying. I also have a `ListView.setCacheColorHint()` line in there, which does _not_ cause the scroll position to reset. – pvans Feb 27 '12 at 04:08
0

Did the same in post execute of Async Task used following code worked for me

 Cursor cursor = mDataHelper.getWritableDatabase().query(
                        DataContract.Incares.TABLE_NAME,  // Table to Query
                        null, // all columns
                        null, // Columns for the "where" clause
                        null, // Values for the "where" clause
                        null, // columns to group by
                        null, // columns to filter by row groups
                        DataContract.Incares.UUID +" DESC" // sort order
                );
CursorAdapter.changeCursor(cursor);
CursorAdapter.notifyDataSetChanged();

with CursorAdapter being a global variable

Amandeep Singh
  • 305
  • 2
  • 11
  • Unless you have a reason for not closing the old cursor, use `CursorAdapter.changeCursor(cursor)`, not "swap" – Renate Mar 16 '21 at 17:20