Обновление: Оказывается, проблема в другом месте. Спасибо @Luksprog за указание на то, что я упустил из виду.
- Проект создается с использованием шаблона навигационного ящика Android Studio. Ящик реализован в классе
NavigationDrawerFragment
. - Фрагмент, содержащий пейджер представления, добавляется при выборе определенного элемента в ящике. Код реализован моей домашней деятельностью.
- Когда экран вращается, вызывается метод
onCreate()
дляNavigationDrawerFragment
, сохраняющий последний выбранный элемент. - И вот что пошло не так — после воссоздания
NavigationDrawerFragment
снова вызовет selectItem(), что вызовет обработчик выбранного пункта меню. Это приводит к тому, что ListFragment восстанавливается Android.
Этого можно избежать, проверив активный пункт меню в моем коде обработчика выбора меню.
Я хочу сохранить последний индекс страницы просмотра ViewPager
, когда действие воссоздается по какой-либо причине, например. изменение ориентации.
ViewPager
находится в Fragment
(с именем ListFragment
), который прикреплен к действию. Я использую библиотеку совместимости, поэтому фрагмент является подклассом android.support.v4.app.Fragment
.
Я подумал, что это можно сделать, переопределив метод onSaveInstanceState()
и добавив соответствующую логику в onCreate()
, как указано в документ:
Для правильной обработки перезапуска важно, чтобы ваша активность восстанавливала свое предыдущее состояние через обычный жизненный цикл активности, в котором Android вызывает onSaveInstanceState() перед тем, как уничтожить вашу активность, чтобы вы могли сохранить данные о состоянии приложения. Затем вы можете восстановить состояние во время onCreate() или onRestoreInstanceState().
Но ситуация кажется иной для фрагментов. Индекс страницы может быть правильно восстановлен, когда я перехожу от этого ListFragment
к другому действию и нажимаю «назад». Однако, когда я поворачиваю свое устройство, индекс страницы теряется.
Я добавил некоторые журналы, чтобы увидеть, что не так. Из журнала я обнаружил, что хотя onSaveInstanceState()
из ListFragment
(я назову его ListFragment A) вызывается правильно, этот конкретный класс Fragment больше не отображается в действии. Когда ориентация изменилась и действие воссоздано, Android вызывает onSaveInstanceState()
, а затем onDetach()
, чтобы отсоединить этот фрагмент. Затем Android создает новый экземпляр ListFragment
(я назову его ListFragment B) и прикрепляет его к новой чередующейся активности. Этот ListFragment B имеет пустой savedInstanceState
, переданный конструктору, и, таким образом, последний индекс страницы (и любая конфигурация в saveInstanceState фрагмента A) потеряны.
На самом деле новый экземпляр ListFragment
будет создаваться каждый раз, когда происходит поворот экрана, но, похоже, старые не будут уничтожены. Я вижу журналы, как показано ниже, когда я поворачиваю устройство:
D/ListFragment﹕ [1110257048] onSaveInstanceState() called, storing last page index 3
D/ListFragment﹕ [1109835992] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1108826176] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1108083096] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1106541040] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1108316656] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1109134136] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1108630992] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1108592888] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1109729064] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1110257048] onDestroy()
D/ListFragment﹕ [1110257048] onDetach()
D/ListFragment﹕ [1109835992] onDestroy()
D/ListFragment﹕ [1109835992] onDetach()
D/ListFragment﹕ [1108826176] onDestroy()
D/ListFragment﹕ [1108826176] onDetach()
D/ListFragment﹕ [1108083096] onDestroy()
D/ListFragment﹕ [1108083096] onDetach()
D/ListFragment﹕ [1106541040] onDestroy()
D/ListFragment﹕ [1106541040] onDetach()
D/ListFragment﹕ [1108316656] onDestroy()
D/ListFragment﹕ [1108316656] onDetach()
D/ListFragment﹕ [1109134136] onDestroy()
D/ListFragment﹕ [1109134136] onDetach()
D/ListFragment﹕ [1108630992] onDestroy()
D/ListFragment﹕ [1108630992] onDetach()
D/ListFragment﹕ [1108592888] onDestroy()
D/ListFragment﹕ [1108592888] onDetach()
D/ListFragment﹕ [1109729064] onDestroy()
D/ListFragment﹕ [1109729064] onDetach()
D/ListFragment﹕ [1110903656] onAttach()
D/ListFragment﹕ [1110903656] onCreate()
D/ListFragment﹕ [1110903656] savedInstanceState is not NULL.
D/ListFragment﹕ [1110903656] Retrieving last page index 3
D/ListFragment﹕ [1110905248] onAttach()
D/ListFragment﹕ [1110905248] onCreate()
D/ListFragment﹕ [1110905248] savedInstanceState is not NULL.
D/ListFragment﹕ [1110905248] Retrieving last page index 0
D/ListFragment﹕ [1110906440] onAttach()
D/ListFragment﹕ [1110906440] onCreate()
D/ListFragment﹕ [1110906440] savedInstanceState is not NULL.
D/ListFragment﹕ [1110906440] Retrieving last page index 0
D/ListFragment﹕ [1110907632] onAttach()
D/ListFragment﹕ [1110907632] onCreate()
D/ListFragment﹕ [1110907632] savedInstanceState is not NULL.
D/ListFragment﹕ [1110907632] Retrieving last page index 0
D/ListFragment﹕ [1110908824] onAttach()
D/ListFragment﹕ [1110908824] onCreate()
D/ListFragment﹕ [1110908824] savedInstanceState is not NULL.
D/ListFragment﹕ [1110908824] Retrieving last page index 0
D/ListFragment﹕ [1110910016] onAttach()
D/ListFragment﹕ [1110910016] onCreate()
D/ListFragment﹕ [1110910016] savedInstanceState is not NULL.
D/ListFragment﹕ [1110910016] Retrieving last page index 0
D/ListFragment﹕ [1110911208] onAttach()
D/ListFragment﹕ [1110911208] onCreate()
D/ListFragment﹕ [1110911208] savedInstanceState is not NULL.
D/ListFragment﹕ [1110911208] Retrieving last page index 0
D/ListFragment﹕ [1110912400] onAttach()
D/ListFragment﹕ [1110912400] onCreate()
D/ListFragment﹕ [1110912400] savedInstanceState is not NULL.
D/ListFragment﹕ [1110912400] Retrieving last page index 0
D/ListFragment﹕ [1110913592] onAttach()
D/ListFragment﹕ [1110913592] onCreate()
D/ListFragment﹕ [1110913592] savedInstanceState is not NULL.
D/ListFragment﹕ [1110913592] Retrieving last page index 0
D/ListFragment﹕ [1110914784] onAttach()
D/ListFragment﹕ [1110914784] onCreate()
D/ListFragment﹕ [1110914784] savedInstanceState is not NULL.
D/ListFragment﹕ [1110914784] Retrieving last page index 0
D/HomeActivity﹕ fragment updated
D/ListFragment﹕ [1110914784] onCreateView()
D/ListFragment﹕ [1111031048] onAttach()
D/HomeActivity﹕ Fragment attached.
D/ListFragment﹕ [1111031048] onCreate()
D/ListFragment﹕ [1111031048] savedInstanceState is NULL.
D/ListFragment﹕ [1111031048] onCreateView()
D/ListFragment﹕ [1111031048] onResume(), restoring page index 0
Это журнал после того, как я повернул экран около 10 раз. Число в теге — это классы hashCode()
. Строки выше показывают, что onSaveInstanceState()
и onCreate()
из ранее созданных фрагментов по-прежнему вызываются даже после того, как они заменены последним (1111031048).
Обратите внимание, что я не вызывал setRetainInstance()
в классе фрагментов. На самом деле, я пробовал и setRetainInstance(false)
, и setRetainInstance(true)
, но это ничего не меняет.
Я сделал что-то не так здесь? Я понимаю, что ListFragment
нужно воссоздать, но почему savedInstanceState
равно null? И если это ожидаемое поведение, как правильно решить мою задачу, т.е. сохранить индекс страницы при изменении конфигурации?
Должна быть возможность сделать индекс страницы статической переменной класса, но я не уверен, действительно ли это решает проблему или просто скрывает ее (потому что я чувствую утечку памяти в журнале выше).
super
для всех переопределенных действий и методов фрагментов (таких какonCreate
,onSaveInstanceState
) и т. д.? - person Ari   schedule 24.01.2014ViewPager
, не добавляется снова (по ошибке) вашим кодом после поворота, заменяя сохраненный? - person user   schedule 24.01.2014