Снятие фрагмент не вызывая данные метода onsaveinstance()

мое приложение для Android имеет ActionBar что меняет, что Fragment занимает определенное FrameLayout. Я пытаюсь использовать onSaveInstanceState чтобы сохранить состояние фрагмента при изменении вкладки, чтобы его можно было восстановить в onCreateView.

проблема onSaveInstanceState никогда не вызывается. The Fragment ' s onDestroyView и onCreateView методы называются, но Bundle поставляемый в onCreateView остается null.

может кто-нибудь объяснить мне, когда onSaveInstanceState на самом деле называется, как я можете убедиться, что он вызывается при переключении вкладок или лучшие практики для сохранения и восстановления состояния Fragment когда он отсоединяется и повторно присоединяется?

фрагмент:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.event_log, container, false);

    // Retrieve saved state
    if (savedInstanceState != null){
        System.out.println("log retrieved");
    } else {
        System.out.println("log null");
    }

    return view;
}

@Override
public void onSaveInstanceState(Bundle outState) {
    System.out.println("log saved");
    super.onSaveInstanceState(outState);
    // more code
}

действие:

/**
 * Detach the current Fragment, because another one is being attached.
 */
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    if (tab.getText().equals(getString(R.string.tab_events))){
        if (frEventLog != null) {
            ft.detach(frEventLog);
    }
}

1 ответов


Fragment#onSaveInstanceState вызывается только тогда, когда Activity хостинг Fragment разрушен и есть шанс, что вы можете вернуться к той же деятельности и фрагмент еще добавил FragmentManager. Наиболее распространенным случаем было бы вращение экрана.

я думаю, что ваш Fragment также нужно сделать setRetainInstance(true) на onCreate например. Хотя не совсем уверен в этом.

вы также должны увидеть, что этот метод вызывается при нажатии кнопки home кнопка, например. Это уничтожит действие, но вы можете вернуться к нему, используя список задач, например.

если вы просто detach() фрагмент все, что вам нужно сделать, чтобы получить его обратно, чтобы попросить FragmentManager для него.

есть два примера, на которые вы должны взглянуть:

ActionBar FragmentTabs и TabHost FragmentTabs

на TabHost пример использования

ft.add(containerId, fragment, tag);
// later
fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag);

найти экземпляры ранее добавленных Fragments, работает до вас remove() a Fragment


о onCreateView / onDestroyView: это называется как только фрагмент отсоединяется, потому что в следующий раз, когда вы прикрепите его, нужно создать новый View. Обратите внимание, что Fragment#onDetached() не вызывается, когда вы detach() фрагмент, потому что он все еще привязан к Activity. Он только отделен от иерархии представлений.


есть еще один хороший пример того, как сохранить фрагмент состояние / как использовать фрагменты, чтобы сохранить состояние в Android Training -Кэширование Растровых Изображений.

в этом примере отсутствует критическая строка:

public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) {
    RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG);
    if (fragment == null) {
        fragment = new RetainFragment();
        fm.beginTransaction().add(fragment, TAG).commit(); // << add this
    }
    return fragment;
}