Почему мои фрагменты onSaveInstanceState () не вызывают? - PullRequest
13 голосов
/ 23 февраля 2012

У меня есть фрагмент, который имеет свое состояние (выбранные кнопки и т. Д.). Это состояние теряется при повороте экрана.

Упражнение, содержащее фрагмент, имеет макет портрета в / res / layout / и почти идентичный макет ландшафта в / res / layout-land /. Обе схемы содержат фрагмент примерно так:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <fragment
        android:id="@+id/testFragment"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        class="au.com.x.y.TestFragment" />
...</LinearLayout>

Класс фрагмента, с которым я тестировал:

public class TestFragment extends android.support.v4.app.Fragment {
    private static final String TAG = "TestFragment";
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate(): " + 
                (savedInstanceState != null ? "NOT NULL" : "NULL"));
    }
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.i(TAG, "onActivityCreated(): " + 
                (savedInstanceState != null ? "NOT NULL" : "NULL"));
    }
    public void onSaveInstanceState(Bundle state) {
        super.onSaveInstanceState(state);
        Log.i(TAG, "onSaveInstanceState()");
        state.putString("saved_thing", "some_value");
    }
    public View onCreateView(
        LayoutInflater inflater,
        ViewGroup container,
        Bundle b) { ... }
}

Обратите внимание, что я использую пакет поддержки pre-3.0 для фрагментов, добавленных через ActionBarSherlock.

LogCat дает мне:

BEFORE SCREEN ROTATION (PORTRAIT):
02-23 11:45:58.015: I/TestFragment(22629): onCreate(): NULL
02-23 11:45:58.015: I/TestFragment(22629): onCreateView()
02-23 11:45:58.035: I/TestFragment(22629): onActivityCreated(): NULL
AFTER SCREEN ROTATION (LANDSCAPE):
02-23 11:46:00.615: I/TestFragment(22629): onCreate(): NULL
02-23 11:46:00.615: I/TestFragment(22629): onCreateView()
02-23 11:46:00.635: I/TestFragment(22629): onActivityCreated(): NULL

Как видите, onSaveInstanceState() никогда не вызывается, и фрагмент всегда получает нулевой savedInstanceState, как в onCreate(), так и onActivityCreated().

Я пытался myFragment.setRetainInstance(true) в своей деятельности onCreate(), но это ничего не изменило.

У моего onSaveInstanceState() есть @Override, поэтому я знаю, что это не что-то глупое, как опечатка.

Я посмотрел на один из примеров ActionBarSherlock (com.actionbarsherlock.sample.shakespeare) и на его фрагментах методы onSaveInstanceState() были вызваны правильно. Насколько я могу судить, этот пример написан именно так, как мой код & mdash; фрагменты, включенные как в макет, так и в XML-файл компоновки. Я даже построил этот пример, используя точно такую ​​же версию ActionBarSherlock, что и мой основной проект, и сохранение состояния экземпляра прекрасно работает для этого примера.

Как сохранить состояние фрагментов при поворотах экрана? Почему не звонят onSaveInstanceState()?

Ответы [ 2 ]

23 голосов
/ 23 февраля 2012

Вы можете включить myFragment.setRetainInstance(true) для сохранения состояния, но оно делает это «автоматически», то есть сохраняет значения, назначенные вашим членам класса, и НЕ использует onSaveInstanceState (и, следовательно, saveInstanceState всегда равно null).

Убедитесь, что FragmentActivity, на котором размещен этот фрагмент, не переопределяет onSaveInstanceState или когда это происходит, он должен вызвать super.onSaveInstanceState(Bundle).

0 голосов
/ 22 ноября 2014

Если фрагменту при вращении требуется другой ресурс макета, setRetainInstance(true) использовать нельзя.На этой странице показан жизненный цикл фрагмента с setRetainInstance(true).

. Оригинальная идея заключается в использовании onSaveInstanceState() для сохранения всех данных членов, как и в обычном действии.Однако по какой-то причине onSaveInstanceState() не вызывается.Но FragmentActivity правильно, как предложил @Eric Kok).Лучшее решение, которое я нашел, это использовать Аргументы Фрагмента.

См. решение от Федор Волчек , это просто.Просто работайте так, как если бы outState в onSaveInstanceState () и savedInstanceState в onViewCreated ().

...