4

I got a listview is an infinite scroll list ie when you get to the bottom of the data set it will loads more. sometimes I could be 5 or 6 pages down a list view and when I accidentally change the phone orientation, the listview jumps to the top. I can't try to remember the scroll position and restore it because data must be loaded from the internet for each page (infinite scrolling)

I don't want to lock my apps rotation. How can I stop the list jumping to the top everytime the orientation changes?

I have also tried the following on my fragment activity but it had no effect

android:configChanges="orientation"

Perhaps it's because i am using a fragment and not an activity?

code511788465541441
  • 20,207
  • 61
  • 174
  • 298

2 Answers2

2

See Maintain/Save/Restore scroll position when returning to a ListView for more discussion and options, but the following method worked for me:

Make a class level variable to save the scroll position and also a key for the state:

static final String STATE_SCROLL_POSITION = "scrollPosition";
int savedPosition = 0;

Override onSaveInstanceState to get the current position before rotation.

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    // Save the user's current game state
    int currentPosition = lvTests.getFirstVisiblePosition();
    savedInstanceState.putInt(STATE_SCROLL_POSITION,
            currentPosition);

    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}

Then get the saved position back when the activity is recreated:

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    savedPosition = savedInstanceState
            .getInt(STATE_SCROLL_POSITION);
    listView.setSelection(savedPosition);

}

In one of my activities I used an AsyncTask (as a subclass in my activity) to populate my ListView and had to restore the position in the onPostExecute method.

@Override
protected void onPostExecute(ArrayList<Test> result) {

    adapter = new MyListAdapter(getApplicationContext(), result);
    lvTests.setAdapter(adapter); 

    lvTests.setSelection(savedPosition); // position is restored here
}

If you populate your listview in another way then just make sure you set the scroll position after you set the adapter.

I did these within an Activity but it should work with fragments, too.

Community
  • 1
  • 1
Suragch
  • 364,799
  • 232
  • 1,155
  • 1,198
0

One way you could solve this is by making use of the onSavedInstanceState and onRestoreInstanceState . Whenever the screen orientation changes save the data of the listview and restore it. Everytime android changes orientation it has to draw all over again. By saving this data you can then work your way around by loading all the previous loaded data in the listview and scroll there with with the following:

For a direct scroll:

getListView().setSelection(21);

For a smooth scroll:

getListView().smoothScrollToPosition(21); 
Fergers
  • 453
  • 2
  • 7
  • 24