Сохранение пользовательского интерфейса при изменении ориентации — onSaveInstanceState не работает должным образом, если сохраняется фрагмент

Использование compat lib v1 (не использование v2|3 из-за некоторых ошибок); вариант этого вопроса.

У меня есть фрагмент, пользовательский интерфейс которого имеет различные элементы управления, состояние которых я хочу сохранить при изменении ориентации.

Родительская активность уничтожается при изменении ориентации (ПОЖАЛУЙСТА, не говорите мне об изменениях манифеста, чтобы избежать воссоздания активности!!!!).

Фрагмент вызывает setRetainInstance(true).

1) Теперь я понимаю, что представления с уникальными идентификаторами должны сохранять некоторое состояние, скажем, при изменении ориентации. Учитывая это, я бы ожидал ненулевой пакет в onCreateView|onActivityCreated, но он нулевой.

2) В любом случае, если я сохраняю состояние в onSaveInstanceState (при условии, что я вызываю super), я все равно получаю нулевой пакет в 'onCreateView|onActivityCreated`

3) Если я не вызываю setRetainInstance(true), то я ДЕЙСТВИТЕЛЬНО получаю ненулевой пакет в onCreateView|onActivityCreated, даже если у меня нет метода `onSaveInstanceState'.

У меня есть вопросы: работает ли это так, как ожидалось, и мое понимание жизненного цикла нарушено? Несмотря на это, я предполагаю, что лучшим путем для меня было бы сохранить фрагмент, а затем самостоятельно поддерживать состояние элементов управления внутри фрагмента.

Заранее спасибо. Питер.


person PJL    schedule 20.10.2011    source источник
comment
Вам удалось это решить? У меня точно такая же проблема.   -  person blindstuff    schedule 07.12.2011
comment
@blindstuff Нет, до сих пор не понял, ошибка это или функция, учитывая, что я звоню setRetainInstance(true). Учитывая, что я получаю ненулевой пакет, если, скажем, приложение уничтожается из-за нехватки памяти, тогда, возможно, это функция. В основном я работаю, сохраняя состояние элементов управления в onDestroyView и используя их для восстановления элементов управления в onCreateView, когда пакет равен нулю. Точно так же я сохраняю состояние отключения в onSaveInstanceState.   -  person PJL    schedule 07.12.2011
comment
Спасибо, я боялся этого, я пытаюсь сохранить AsyncTask во время ротации, поэтому я не могу выбрать маршрут, которым вы следовали, я думаю. Я также собираюсь опубликовать вопрос, чтобы попытаться привлечь больше внимания к этой теме.   -  person blindstuff    schedule 07.12.2011
comment
Попробуйте использовать последнюю версию (на данный момент 4) ACL. Исправлены некоторые проблемы с setRetainInstance.   -  person Catalin Morosan    schedule 13.12.2011
comment
@kaciula Спасибо, хотя и обновился, чтобы использовать v4, хотя проблема все еще остается.   -  person PJL    schedule 13.12.2011
comment
Если вы используете setRetainInstance(true), то, конечно, пакет будет нулевым. Фрагмент не уничтожается, а только отсоединяется от текущей активности и присоединяется к новой активности. Только когда фрагмент будет уничтожен, вы получите пакет со значениями, которые вы сохранили в onSaveInstanceState. Просто удалите setRetainInstance(true).   -  person Catalin Morosan    schedule 13.12.2011


Ответы (1)


Если вы используете setRetainInstance(true), то, конечно, пакет будет нулевым. Фрагмент не уничтожается, а только отсоединяется от текущей активности и присоединяется к новой активности. Только когда фрагмент будет уничтожен, вы получите пакет со значениями, которые вы сохранили в onSaveInstanceState. Просто удалите setRetainInstance(true) и используйте сохраненные значения в onCreateView() для настройки ваших пользовательских представлений.

person Catalin Morosan    schedule 13.12.2011
comment
Затем я удивлен, что я получаю вызов onSaveInstanceState при вращении, когда вызывается setRetainInstance(true), и, кроме того, состояние элементов управления теряется. Насколько я понимаю, представления с уникальными идентификаторами должны сохранять некоторое состояние, например, при изменении ориентации. - person PJL; 13.12.2011
comment
onCreateView() вызывается независимо от того, используете ли вы setRetainInstance или нет. Таким образом, весь вид будет воссоздан. Какие элементы управления вы на самом деле видите, что они теряют состояние? setRetainInstance(true) следует использовать только в очень специфических ситуациях. Чего именно вы хотите добиться? setRetain.. не сохраняет состояние ваших элементов управления, но поддерживает этот фрагмент, чтобы вы могли сохранять различную информацию в своих переменных-членах. Затем, когда onCreateView вызывается снова, вы можете установить состояние ваших различных представлений с помощью информации из ваших переменных-членов. - person Catalin Morosan; 14.12.2011
comment
Спасибо, я понимаю, что onCreateView вызывается независимо, и я сам управляю состоянием элементов управления. Я также понимаю, что в основном все работает так, как ожидалось, однако я все еще удивлен тем, что onSaveInstanceState вызывается при вращении, что создает у меня ложное впечатление, что onCreateView затем будет вызываться с ненулевым пакетом. - person PJL; 14.12.2011