Как сохранить состояние фрагмента, имеющего listview

Вот ситуация. Я хочу перейти от фрагмента A- > B- > C.

В B Fragment есть listview. При щелчке элемента открываем подробный фрагмент C Fragment. Конечно, я использовал метод замены и добавил addtoBackStack (null), в то время как transactiong от B до C, чтобы в Back нажать его, чтобы вернуться в B.

Все идет хорошо. Но когда я возвращаюсь к B из C, представление обновляется, и, следовательно, веб-сервис снова вызывается. Я не хочу этого делать. Я хочу сохранить состояние фрагмента B со списком.

Я получил сообщение о сохранении экземпляра, но это не помогло.

Любая помощь очень ценится.

Спасибо.

Ответ 1

Как описано здесь, вы можете использовать onSaveInstanceState() для сохранения данных в Bundle и получения этих данных в методе onRestoreInstanceState().

Часто setRetainState (true) упоминается как способ сохранить состояние ui в фрагменте, но он не работает для вас, потому что вы используете backstack.

Таким образом, для вас может быть полезным сохранить прокрутку в onSaveInstanceState() и восстановить его в onRestoreInstanceState() следующим образом:

public class MyListFragment extends ListFragment {

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

     int index = this.getListView().getFirstVisiblePosition();
     View v = this.getListView().getChildAt(0);
     int top = (v == null) ? 0 : v.getTop();

     outState.putInt("index", index);
     outState.putInt("top", top);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    [...]
    if (savedInstanceState != null) {
        // Restore last state for checked position.
        index = savedInstanceState.getInt("index", -1);
        top = savedInstanceState.getInt("top", 0);
    }
    if(index!=-1){
     this.getListView().setSelectionFromTop(index, top);
  }

}

Далее вы можете найти более подробный аналогичный пример здесь.

Ответ 2

Я решил эту проблему, создав свой Adapter on onCreate() вместо onCreateView().

Это потому, что (я думаю) фрагмент, который добавлен в backstack, потерял свой вид, а затем он должен воссоздать представление. onCreateView() вызывается и, кстати, воссоздает ваш адаптер.

Ответ 3

вы можете сохранить свой ui в oncreate. когда в onCreateView добавьте только макет. так что состояние представления может сохранить идеальное.

это мой sv:

в oncreate

 LayoutInflater inflater = (LayoutInflater)
            ctx.getSystemService(ctx.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.pulltorefreshgridview, null);
    mPullRefreshGridView = (PullToRefreshGridView) view
            .findViewById(R.id.listcate_pullrefresh_gridview);

сильный текст в onCreateView

if (rootView != null) ((LinearLayout)rootView).removeAllViews();
View v = inflater.inflate(R.layout.listcate_fragment, container, false);
rootView = v;


    ((LinearLayout) v).addView(mPullRefreshGridView,
            new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.FILL_PARENT,
                    LinearLayout.LayoutParams.FILL_PARENT));

Ответ 4

Я думаю, что вы можете сохранить свою позицию ListView непосредственно перед тем, как покинуть фрагмент B. Возможно, сделайте это в фрагменте B onStop(). И когда вы вернетесь, вы можете получить эту позицию и восстановить ее в ListView, сделайте это, например, в фрагменте B onStart(). Данные позиции могут быть сохранены в Activity, поэтому он не будет потерян даже отделяемым фрагментом.

Следует отметить, что (я был в ловушке этого), если сохраненные данные о местоположении обновлены фоновым сервисом, вы должны избегать восстановления его в ListView до этапа жизненного цикла onStart() фрагмента B, потому что на самом деле структура сохранит состояние представления перед тем, как покинуть фрагмент и восстановить его при возврате. Поэтому, если вы восстановите свою позицию до того, как инфраструктура сделает это, данные восстановления структуры будут переопределять ваши.