Djanito
Djanito

Reputation: 197

Restore items and scroll position in listview on orientation change

I tried, by several means, to restore data of a listview when the user rotate his phone..However, I have some difficulties due to the fact that when I turn the screen once, it works, but when I turn it over another time, it no longer works. In addition, I tried to restore the scroll position but without success.

So I would like to know the best way to do this.


My code:

private ListView item_container;
private ArrayList<Song.Hits> values;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    item_container = findViewById(R.id.bottom_popup_container);
}

And when I finish to retrieve data from an API, I load them into the listview (and I save the data):

@Override
public void onRequestFinish(ArrayList<Song.Hits> hits) {
    if (!hits.isEmpty()) {
        CAdapter adapter = new CAdapter(hits);
        item_container.setAdapter(adapter);
        values = adapter.getHits();
    };
}

Finally, I overwrite these 2 methods to save the position and the items of the listview.

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        outState.putParcelableArrayList("list",  values);
        outState.putParcelable("pos", item_container.onSaveInstanceState());
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
            ArrayList<Song.Hits> values = savedInstanceState.getParcelableArrayList("list");
            if (values != null) {
                CAdapter adapter = new CAdapter(values);
                item_container.setAdapter(adapter);
                item_container.onRestoreInstanceState(savedInstanceState.getParcelable("pos"));
            }
    }

Upvotes: 0

Views: 516

Answers (3)

EpicPandaForce
EpicPandaForce

Reputation: 81568

To an unrelated degree, you should probably be using RecyclerView instead of ListView, which nowadays also supports a custom state restoration policy so that the scroll state is automatically preserved until data is set.

Anyways, following current approach, should be as simple as

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    ArrayList<Song.Hits> values = savedInstanceState.getParcelableArrayList("list");

should be

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    values = savedInstanceState.getParcelableArrayList("list");

Upvotes: 1

Ezequiel Zanetta
Ezequiel Zanetta

Reputation: 74

You should do the same checking but on onCreate because onRestoreInstanceState is not always called, is kind of tricky.

You can check this from the documentation:

This method is called after onStart() when the activity is being re-initialized from a previously saved state, given here in savedInstanceState. Most implementations will simply use onCreate(Bundle) to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation. The default implementation of this method performs a restore of any view state that had previously been frozen by onSaveInstanceState(Bundle).

Move your logic to onCreate and you'll be fine

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    item_container = findViewById(R.id.bottom_popup_container);

    if (savedInstanceState != null) {
        ArrayList<Song.Hits> values = savedInstanceState.getParcelableArrayList("list");
        if (values != null) {
            CAdapter adapter = new CAdapter(values);
            item_container.setAdapter(adapter);
                item_container.onRestoreInstanceState(savedInstanceState.getParcelable("pos"));
        }
    }
}

Upvotes: 0

Hari Kiran
Hari Kiran

Reputation: 208

You should also update the OnCreate method or override OnPostCreate method and add the logic you used in onRestoreInstanceState upon checking if savedInstanceState!=null

Upvotes: 0

Related Questions