Android ListView with CursorAdapter has Incorrect Scroll Position after Requery is called when new items are added
Asked Answered
B

2

7

Here's the scenario: I've got a simple ListView displaying a twitter feed. I have a CursorAdapter which is fetching tweets from sqlite. When I call requery() on my cursor, I expect that new tweets will be fetched that have since been added to the database. This all works fine, and the new items are even visible in the ListView after this happens.

The Problem is the scroll position seems to be saved based on the item position offset. So let's say the first visible position in my ListView is 4. When I requery and 2 new items are added to the top of the list, the ListView keeps the first visible item scroll position as 4, however since there's two new items in the list, I now see a different item at position 4 than before I refreshed. This image illustrates the before and after: enter image description here

Notice how Before, Tweet D is the first visible item and afterwards, Tweet B now becomes the first visible item.

My Question is, how do I keep the same scroll position based on cursor positon when calling requery, so that in this example, Tweet D would still be the first visible item after a requery?

Blazon answered 9/1, 2013 at 14:17 Comment(0)
H
3

I had a similar issue in one of my projects. Here's how I solved it. Although it's not exactly the same case. Hope it helps.

Before you update the list, save the scroll position this way -

int position = getListView().getFirstVisiblePosition();
View v = getListView().getChildAt(0);
int top = v == null ? 0 : v.getTop();

And then after you update the list, you will know how many items you've added. So you can call

yourlistview.setSelectionFromTop(position + <number of items added>, top);
Hokku answered 10/1, 2013 at 13:46 Comment(2)
My Main issue with this is that all my items are not the same height, so scrolling like this may not get the 'exact' position it was at previously, for example if an item is half visible...Blazon
Did you try it? Because even my list has rows of variable heights. But works perfectly. int top = v == null ? 0 : v.getTop(); This part actually handles the case when an item is half visible.Hokku
P
0

My suggestion would be to keep track of the number of items in the list. Once you know that, as part of the update you can add the difference to between the old count and the new count.

Psuedo Code

on_update

  offset+= (list_view.length() - list_size)
  list_size = list_view.length()
Pokelogan answered 10/1, 2013 at 13:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.