Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restore fragment state after resume w/o savedInstanceState?

in my app an FragmentActivity contains a simple ListFragment and I want to preserve the position to which the user has scrolled to. I did the following:

private int initialScrollPosition = 0;
private int initialScrollYOffset = 0;

@Override
public void onSaveInstanceState (Bundle outState) {
    outState.putInt(SCROLL_POSITION, this.getListView().getFirstVisiblePosition());
    View firstVisibleItemView = this.getListView().getChildAt(0);
    outState.putInt(SCROLL_Y_OFFSET, (firstVisibleItemView == null) ? 0 : firstVisibleItemView.getTop());
}

@Override
public void onActivityCreated (Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    this.restoreState(savedInstanceState);
}

private void restoreState(Bundle savedInstanceState) {
    if(savedInstanceState != null
            && savedInstanceState.containsKey(SCROLL_POSITION)) {
        this.initialScrollPosition = savedInstanceState.getInt(SCROLL_POSITION);
    }
    if(savedInstanceState != null
            && savedInstanceState.containsKey(SCROLL_Y_OFFSET)) {
        this.initialScrollYOffset = savedInstanceState.getInt(SCROLL_Y_OFFSET);
    }
}

@Override
public void onStart () {
    super.onStart();
    // some other GUI stuff
    this.getListView().setSelectionFromTop(this.initialScrollPosition, this.initialScrollYOffset);
}

This solution works fine for things like display orientation changes or moving from one Activity of my app to the next.

But if I fire up the app, scroll a bit, go back to home, and restore the App from Recents, onActivityCreated (or any other callbacks with the savedInstanceState Bundle) is not called and therefore the state cannot be restored.

Therefore I have two questions:

  1. What can I do to get the savedInstanceState after resuming without the onXXXCreated callbacks?
  2. What exactly is the lifecycle doing there. I'd like to understand, why my approach fails.

Thank you very much for any insight!

Solution:

Thx to André! I changed my onSaveInstanceState to this:

@Override
public void onSaveInstanceState (Bundle outState) {
    this.initialScrollPosition = this.getListView().getFirstVisiblePosition();
    View firstVisibleItemView = this.getListView().getChildAt(0);
    this.initialScrollYOffset = (firstVisibleItemView == null) ? 0 : firstVisibleItemView.getTop();
    outState.putInt(SCROLL_POSITION, this.initialScrollPosition);
    outState.putInt(SCROLL_Y_OFFSET, this.initialScrollYOffset);
}
like image 584
Chris Avatar asked Nov 01 '25 06:11

Chris


1 Answers

If your app is brought to front using the recent apps button, it might be that it isn't recreated, because the system didn't finish it yet. In that case only onResume() and following callbacks are invoked.

Conclusion: try to restore your position in onResume(), store the positions in onPause() (for recent app switches where the activity isn't recreated), extract the positions from savedInstanceState bundle (for orientation change where the activity is recreated).

like image 72
Trinimon Avatar answered Nov 02 '25 19:11

Trinimon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!