В чем разница между FragmentPagerAdapter и FragmentStatePagerAdapter?
В чем разница между FragmentPagerAdapter
и FragmentStatePagerAdapter
?
О FragmentPagerAdapter
руководство Google говорит:
Эта версия пейджера лучше всего подходит для использования, когда имеется несколько статических фрагментов, которые нужно пролистать, например, набор вкладок. Фрагмент каждой страницы, которую пользователь посещает, будет храниться в памяти, хотя его иерархия просмотра может быть разрушена, если она не видна. Это может привести к использованию значительного объема памяти, поскольку экземпляры фрагмента могут удерживать произвольное количество состояния. Для больших наборов страниц рассмотрите FragmentStatePagerAdapter
.
А насчет FragmentStatePagerAdapter
:
Эта версия пейджера более полезна, когда имеется большое количество страниц, и работает больше как представление списка. Когда страницы не видны пользователю, весь их фрагмент может быть уничтожен, сохраняя только сохраненное состояние этого фрагмента. Это позволяет пейджеру удерживать гораздо меньше памяти, связанной с каждой посещаемой страницей, по сравнению с FragmentPagerAdapter
за счет потенциально больших накладных расходов при переключении между страницами.
Так что у меня всего 3 фрагмента. Но все они являются отдельными модулями с большим объемом данных.
Fragment1
обрабатывает некоторые данные (которые вводят пользователи) и передает их посредством действия в Fragment2
, который является простым ListFragment
. Fragment3
также является ListFragment
.
Итак, мои вопросы: какой адаптер я должен использовать? FragmentPagerAdapter
или FragmentStatePagerAdapter
?
Ответы
Ответ 1
Как говорят документы, подумайте об этом таким образом. Если вы будете делать приложение, например, книжное устройство, вы не захотите сразу загрузить все фрагменты в память. Вы хотите загрузить и уничтожить Fragments
по мере чтения пользователем. В этом случае вы будете использовать FragmentStatePagerAdapter
. Если вы просто показываете 3 "вкладки", которые не содержат много тяжелых данных (например, Bitmaps
), тогда FragmentPagerAdapter
может вам подойдет. Кроме того, имейте в виду, что ViewPager
по умолчанию будет загружать 3 фрагмента в память. Первый Adapter
, который вы упомянули, может уничтожить иерархию View
и загрузить ее при необходимости, второй Adapter
сохраняет только состояние Fragment
и полностью уничтожает его, если пользователь затем возвращается на эту страницу, состояние получено.
Ответ 2
-
FragmentPagerAdapter
хранит весь фрагмент в памяти и может
увеличивайте накладные расходы памяти, если большое количество фрагментов используется в
ViewPager
.
-
В противоположность своему брату, FragmentStatePagerAdapter
хранит только
savedInstanceState фрагментов и уничтожает все фрагменты, когда
они теряют фокус.
-
Поэтому FragmentStatePagerAdapter
следует использовать, когда мы должны
использовать динамические фрагменты, такие как фрагменты с виджетами, в качестве своих данных
может храниться в savedInstanceState
. Также он не будет влиять на производительность, даже если имеется большое количество
фрагменты.
-
В противном случае его брат FragmentPagerAdapter
следует использовать, когда
нам нужно сохранить весь фрагмент в памяти.
-
Когда я говорю, что весь фрагмент хранится в памяти, это означает, что его
экземпляры не будут уничтожены и создадут издержки памяти.
Поэтому рекомендуется использовать FragmentPagerAdapter
только тогда, когда
низкое количество фрагментов для ViewPager
.
-
Было бы еще лучше, если бы фрагменты были статичными, поскольку они
не иметь большого количества объектов, экземпляры которых были бы
сохранены.
Чтобы быть более подробным,
FragmentStatePagerAdapter:
-
с FragmentStatePagerAdapter
, ваш ненужный фрагмент
destroy.The совершает полное удаление
фрагмент из вашей активности FragmentManager
.
-
Состояние в FragmentStatePagerAdapter
происходит от того, что оно
сохранит ваш фрагмент Bundle
от savedInstanceState
, когда
он будет уничтожен. Когда пользователь перейдет обратно, новый фрагмент будет
восстановлено с использованием состояния фрагмента.
FragmentPagerAdapter:
-
При сравнении FragmentPagerAdapter
ничего не делает. Когда
фрагмент больше не нужен. FragmentPagerAdapter
calls
detach(Fragment)
для транзакции вместо remove(Fragment)
.
-
Это разрушает представление фрагмента, но оставляет экземпляр фрагмента
живой в FragmentManager
.so фрагменты, созданные в
FragmentPagerAdapter
никогда не уничтожаются.
Ответ 3
Что-то, что явно не указано в документации или ответах на этой странице (хотя это и подразумевается @Naruto), заключается в том, что FragmentPagerAdapter
не будет обновлять фрагменты, если данные во Фрагменте меняются, потому что он сохраняет фрагмент в памяти.
Таким образом, даже если у вас есть ограниченное количество фрагментов для отображения, если вы хотите обновить свои фрагменты (например, повторите запуск запроса для обновления спискаView в фрагменте), вам необходимо использовать FragmentStatePagerAdapter.
Все мое дело в том, что количество фрагментов и то, что они похожи, не всегда являются ключевым аспектом. Независимо от того, являются ли ваши фрагменты динамическими, также является ключевым.
Ответ 4
Вот жизненный цикл журнала каждого фрагмента в ViewPager
который имеет 4 фрагмента и offscreenPageLimit = 1 (default value)
FragmentStatePagerAdapter
Перейдите к Fragment1 (запуск)
Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart
Перейти к Fragment2
Fragment3: onCreateView
Fragment3: onStart
Перейти к Fragment3
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach
Fragment4: onCreateView
Fragment4: onStart
Перейти к Fragment4
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
FragmentPagerAdapter
Перейдите к Fragment1 (запуск)
Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart
Перейти к Fragment2
Fragment3: onCreateView
Fragment3: onStart
Перейти к Fragment3
Fragment1: onStop
Fragment1: onDestroyView
Fragment4: onCreateView
Fragment4: onStart
Перейти к Fragment4
Fragment2: onStop
Fragment2: onDestroyView
Вывод: FragmentStatePagerAdapter
вызывает onDestroy
когда фрагмент преодолевается offscreenPageLimit
а FragmentPagerAdapter
нет.
Примечание. Я думаю, что мы должны использовать FragmentStatePagerAdapter
для ViewPager
которого много страниц, потому что это хорошо для производительности.
Пример offscreenPageLimit
:
Если мы перейдем к Fragment3, он будет дефрагментировать Fragment1 (или Fragment5, если есть), потому что offscreenPageLimit = 1
. Если мы установим offscreenPageLimit > 1
он не уничтожит.
Если в этом примере мы установили offscreenPageLimit=4
, нет никакого различия между использованием FragmentStatePagerAdapter
или FragmentPagerAdapter
потому что Fragment никогда не вызывает onDestroyView
и onDestroy
когда мы меняем вкладку
Демо-версия Github
Ответ 5
FragmentPagerAdapter
хранит предыдущие данные, которые извлекаются из адаптера, а FragmentStatePagerAdapter
принимает новое значение из адаптера каждый раз, когда он выполняется.
Ответ 6
FragmentStatePagerAdapter = для размещения большого количества фрагментов в ViewPager. Поскольку этот адаптер разрушает фрагмент, когда он не отображается пользователю, и только сохраненное значениеInstanceState фрагмента сохраняется для дальнейшего использования. Таким образом, используется низкий объем памяти и достигается более высокая производительность в случае динамических фрагментов.
Ответ 7
FragmentPagerAdapter хранит весь фрагмент в памяти и может увеличить служебные данные памяти, если в ViewPager используется большое количество фрагментов. В противоположность своему родному брату, FragmentStatePagerAdapter сохраняет только сохраненный экземпляр UnstanceState и уничтожает все фрагменты, когда они теряют фокус.
Поэтому FragmentStatePagerAdapter следует использовать, когда мы должны использовать динамические фрагменты, такие как фрагменты с виджетами, поскольку их данные могут быть сохранены в файле savedInstanceState. Также это не повлияет на производительность, даже если имеется большое количество фрагментов. Напротив, его брат FragmentPagerAdapter следует использовать, когда нам нужно сохранить весь фрагмент в памяти. Когда я говорю, что весь фрагмент хранится в памяти, это означает, что его экземпляры не будут уничтожены и создадут издержки памяти.
Поэтому рекомендуется использовать FragmentPagerAdapter только при наличии небольшого количества фрагментов для ViewPager. Было бы еще лучше, если бы фрагменты были статическими, поскольку у них не было бы большого количества объектов, экземпляры которых будут храниться. Надеюсь, это очистит разницу между Android FragmentPagerAdapter и FragmentStatePagerAdapter. Если вам нравится эта статья, поделитесь ею со своими друзьями в Google+ и Facebook, также как и наша страница на Facebook для получения последних обновлений.