My assumption is it has to do with the "Row graveyard", whenever you use a list view, you're reusing a set of rows, let's say there are 15 rows visible on a device, Android will go ahead and track the states of those 15 rows. Whenever you scroll, the row is dequeued, and a new row is brought in. If you then scroll back up, Android will re-use a row from the row graveyard where it keeps rows that were visible that are no longer visible. This is done to keep memory usage low, and to decrease render times, so a row when it's first rendered will take longer, then successive re-renders of the row will be faster.
This means, to track the scroll offset, you'll need to do some work for yourself. My advice is have a shared class that has static properties which track UI state. Then, when you do a tab switch, you set a property that tracks the absolute y position of the list view. To get this value, you need to know how many items are no longer visible that were previously visible, multiply that by ListItemHeight and add headerHeight, in a custom list view, you can use FirstVisiblePosition to get the position of the adapters first visible item, so
var pos = this.FirstVisiblePosition;
if(pos > 0)
{
absoluteY += (pos - 1) * itemHeight + headerHeight;
}
Where absoluteY
is the scroll offset of the listview, you simple add to it as I've done here, if you don't have the itemHeight and the headerHeight ahead of time, use FindViewById
and get their heights that way.
Hope that makes sense, All this is how it works under Android Xamarin by the way, so you'll need to do some work to figure out how that translates to forms (never used forms)