В FragA
андроиде фрагмент (скажем ) добавляется в backstack, а другой фрагмент (скажем FragB
) попадает на вершину. Теперь на ответный удар FragA
приходит наверх и onCreateView()
называется. Теперь я находился FragA
в определенном состоянии, прежде чем FragB
меня оттолкнули.
Мой вопрос, как я могу восстановить FragA
его предыдущее состояние? Есть ли способ сохранить состояние (например, в Bundle) и если да, то какой метод мне следует переопределить?
android
android-fragments
pankajagarwal
источник
источник
onSaveInstanceState
вызывается только тогда, когда соответствующая активность также завершается.Фрагменты
onSaveInstanceState(Bundle outState)
никогда не будут вызваны, пока активность фрагмента не вызовет его на себе и на прикрепленных фрагментах. Таким образом, этот метод не будет вызываться до тех пор, пока что-то (обычно вращение) не заставит активностьSaveInstanceState
и не восстановит ее позже. Но если у вас есть только одно действие и большой набор фрагментов внутри него (с интенсивным использованиемreplace
) и приложение запускается только в одном ориентированном действии, то оноonSaveInstanceState(Bundle outState)
может не вызываться в течение длительного времени.Я знаю три возможных обходных пути.
Первый:
используйте аргументы фрагмента для хранения важных данных:
Второй, но менее педантичный способ - держать переменные в синглетонах
Третий - не
replace()
фрагменты, аadd()
/show()
/hide()
их вместо.источник
Fragment.onSaveInstanceState()
никогда не звонили. Просто сохраните ваши собственные данные в аргумент, включая элементы в представлении списка или только их идентификаторы (если у вас есть другой централизованный менеджер данных). Нет необходимости сохранять позицию представления списка - она была сохранена и восстановлена автоматически.String persistentVariable = mySavedInstanceState.getString(PERSISTENT_VARIABLE_BUNDLE_KEY);
всегдаnull
. В чем проблема?getArguments()
это ОПРЕДЕЛЕННО путь, включая вложенные фрагменты в ViewPager. Я использую 1 упражнение и меняю местами много фрагментов, и это прекрасно работает. Вот простой тест для проверки любого предложенного решения: 1) перейти от фрагмента A к фрагменту B; 2) изменить ориентацию устройства дважды; 3) нажмите кнопку возврата на устройстве.setArguments(new Bundle());
перезаписывает старый Bundle. Поэтому убедитесь, что вы создали фрагмент только один раз, а затем используйте этот экземпляр вместо того, чтобы каждый раз создавать новый.Просто обратите внимание, что если вы работаете с фрагментами с помощью ViewPager, это довольно просто. Вам нужно только вызвать этот метод:
setOffscreenPageLimit()
.Согласовать с документами:
Подобная проблема здесь
источник
Просто раздуйте свой взгляд на этот раз.
Пример следует:
}
источник
Fragment
ссылается на свое корневое представление, этого не делать. В то время как ссылки на некоторые элементы GC-корня будут, как и глобальное статическое свойство, не-пользовательской переменной потока.Fragment
Экземпляр не является GC-корень, поэтому он может быть мусора. Так же как и его корневой вид.Я работал с проблемой, очень похожей на эту. Так как я знал, что часто буду возвращаться к предыдущему фрагменту, я проверил, был ли фрагмент
.isAdded()
истинным, и если да, то вместо того, чтобы делать a,transaction.replace()
я просто делаю atransaction.show()
. Это удерживает фрагмент от воссоздания, если он уже находится в стеке - сохранение состояния не требуется.Следует также помнить, что, хотя это сохраняет естественный порядок для самих фрагментов, вам все равно может потребоваться обработка самого действия, которое уничтожается и воссоздается при изменении ориентации (конфигурации). Чтобы обойти это в AndroidManifest.xml для вашего узла:
В Android 3.0 и выше, по-
screenSize
видимому, требуется.Удачи
источник
android:configChanges=everythinYouCanThinkOf|moreThingsYouFoundOnTheInternets
в свой манифест. Вместо этого узнайте, как сохранить и восстановить состояние, например, отсюда: speakerdeck.com/cyrilmottier/…Лучшее решение, которое я нашел ниже:
onSavedInstanceState (): всегда вызывается внутри фрагмента, когда действие прекращается (перемещение действия от одного к другому или изменение конфигурации). Таким образом, если мы вызываем несколько фрагментов для одной и той же деятельности, тогда мы должны использовать следующий подход:
Используйте OnDestroyView () фрагмента и сохраните весь объект внутри этого метода. Тогда OnActivityCreated (): проверьте, является ли объект нулевым или нет (поскольку этот метод вызывается каждый раз). Теперь восстановите состояние объекта здесь.
Его работает всегда!
источник
если вы обрабатываете изменения конфигурации в вашей активности фрагмента, указанной в манифесте Android, как это
тогда
onSaveInstanceState
фрагмент не будет вызван, иsavedInstanceState
объект всегда будет нулевым.источник
я не думаю, что
onSaveInstanceState
это хорошее решение. это просто использовать для деятельности, которая была уничтожена.Начиная с Android 3.0 Fragmen был менеджером FragmentManager, условие: одно действие отображает фрагменты Мэнни, когда фрагмент добавляется (не заменяет: он будет воссоздан) в backStack, представление будет удалено. если вернуться к последнему, он будет отображаться как прежде.
Так что я думаю, что fragmentanger и транзакция достаточно хороши, чтобы справиться с этим.
источник
Я использовал гибридный подход для фрагментов, содержащих представление списка. Это кажется производительным, так как я не заменяю текущий фрагмент, а добавляю новый фрагмент и скрываю текущий. У меня есть следующий метод в упражнении, в котором хранятся мои фрагменты:
Я использую этот метод в своем фрагменте (содержащем представление списка) всякий раз, когда на элемент списка нажимают / касаются (и поэтому мне нужно запустить / отобразить фрагмент сведений):
getFragmentTags()
возвращает массив строк, которые я использую в качестве тегов для разных фрагментов, когда добавляю новый фрагмент (см.transaction.add
метод вaddFragment
методе выше).Во фрагменте, содержащем представление списка, я делаю это с помощью метода onPause ():
Затем в onCreateView фрагмента (фактически в методе, который вызывается в onCreateView), я восстанавливаю состояние:
источник
В конце концов, после того, как я попробовал многие из этих сложных решений, мне нужно было только сохранить / восстановить одно значение в моем фрагменте (содержимое EditText), и хотя это может быть не самым элегантным решением, создание SharedPreference и сохранение моего состояния там работали на меня
источник
Простой способ сохранить значения полей в разных фрагментах в деятельности
Создайте экземпляры фрагментов и добавьте вместо замены и удаления
Затем просто покажите и скройте фрагменты вместо того, чтобы снова добавлять и удалять их
;
источник
источник