Восстановить элементы и позицию прокрутки в списке при изменении ориентации - PullRequest
0 голосов
/ 18 июня 2020

Я пытался несколькими способами восстановить данные списка, когда пользователь поворачивает свой телефон ... Однако у меня возникают некоторые трудности из-за того, что когда я поворачиваю экран один раз, он работает, но когда я его поворачиваю в другой раз он больше не работает. Кроме того, я попытался восстановить положение прокрутки, но безуспешно.

Итак, я хотел бы знать, как это сделать лучше всего.


Мой код:

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);
}

И когда я заканчиваю sh извлекать данные из API, я загружаю их в список (и сохраняю данные):

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

Наконец, я перезаписываю эти 2 метода для сохранения позиция и элементы списка.

    @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"));
            }
    }

Ответы [ 3 ]

1 голос
/ 18 июня 2020

В несвязанной степени вам, вероятно, следует использовать RecyclerView вместо ListView, который в настоящее время также поддерживает политику восстановления настраиваемого состояния, чтобы состояние прокрутки автоматически сохранялось до тех пор, пока данные не будут установлены.

В любом случае, следуя текущему подходу, должно быть так просто, как

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

должно быть

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    values = savedInstanceState.getParcelableArrayList("list");
0 голосов
/ 18 июня 2020

Вы должны выполнить ту же проверку, но на onCreate, потому что onRestoreInstanceState не всегда вызывается, это довольно сложно.

Вы можете проверить это из документации:

Этот метод вызывается после onStart(), когда действие повторно инициализируется из ранее сохраненного состояния, указанного здесь в savedInstanceState. Большинство реализаций просто используют onCreate(Bundle) для восстановления своего состояния, но иногда бывает удобно сделать это здесь после того, как вся инициализация была выполнена, или позволить подклассам решать, использовать ли вашу реализацию по умолчанию. Реализация этого метода по умолчанию выполняет восстановление любого состояния просмотра, которое ранее было заморожено onSaveInstanceState(Bundle).

Переместите ваш logi c в onCreate, и все будет в порядке

@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"));
        }
    }
}
0 голосов
/ 18 июня 2020

Вы также должны обновить метод OnCreate или переопределить метод OnPostCreate и добавить logi c, который вы использовали в onRestoreInstanceState, после проверки, если savedInstanceState! = Null

...