Разница между FragmentPagerAdapter и FragmentStatePagerAdapter
в чем разница между FragmentPagerAdapter
и FragmentStatePagerAdapter
?
о FragmentPagerAdapter
руководство Google говорит:
эта версия пейджера лучше всего использовать, когда есть несколько как правило, больше статических фрагментов для пролистывания, таких как набор вешалки. Фрагмент каждой страницы, которую посетит пользователь, будет сохранен память, хотя ее иерархия представлений может быть уничтожена, когда она невидима. Это может привести к использованию значительного объема памяти, так как фрагмент экземпляры могут сохранять произвольное количество состояний. Для больших наборов из страниц рассмотрим FragmentStatePagerAdapter.
и о FragmentStatePagerAdapter
:
эта версия пейджера более полезна, когда есть большое количество страниц, работающих больше как представление списка. Когда страницы не видны пользователь, весь их фрагмент может быть уничтожен, только сохраняя сохраненное состояние этого фрагмента. Это позволяет пейджеру держаться за многое меньше памяти, связанной с каждой посещаемой страницей по сравнению с FragmentPagerAdapter за счет потенциально более накладных расходов, когда переключение между страницами.
Итак, у меня есть только 3 фрагмента. Но все они являются отдельными модулями с большим объемом данных.
Fragment1
обрабатывает некоторые данные (которые вводят пользователи) и передает их через activity в Fragment2
, что просто ListFragment
. Fragment3
тоже ListFragment
.
Итак, мои вопросы are: Какой адаптер лучше использовать? FragmentPagerAdapter
или FragmentStatePagerAdapter
?
6 ответов
как говорят врачи, подумайте об этом таким образом. Если вы должны были сделать приложение, как для чтения книг, вы не захотите загружать все фрагменты в память сразу. Вы хотели бы загрузить и уничтожить Fragments
как пользователь читает. В этом случае вы будете использовать FragmentStatePagerAdapter
. Если вы просто отображаете 3 "вкладки", которые не содержат много тяжелых данных (например,Bitmaps
), то FragmentPagerAdapter
возможно, Вам подойдет. Кроме того, имейте в виду, что ViewPager
по умолчанию будет загружать 3 фрагмента в память. Первый Adapter
вы упомянули, может уничтожить View
иерархия и повторно загрузить его, когда это необходимо, второй Adapter
сохраняет только состояние Fragment
и полностью уничтожает его, если пользователь затем возвращается на эту страницу, состояние извлекается.
FragmentPagerAdapter
хранит весь фрагмент в памяти, и может увеличьте накладные расходы памяти, если используется большое количество фрагментовViewPager
.в противоположность своему брату,
FragmentStatePagerAdapter
только в магазинах savedInstanceState фрагментов и уничтожает все фрагменты, когда они теряют концентрацию.-
FragmentStatePagerAdapter
должно быть использовано когда мы должны в качестве данных используйте динамические фрагменты, например фрагменты с виджетами может быть хранится вsavedInstanceState
.Также это не повлияет на производительность, даже если есть большое количество фрагментарный. в противоположность своему брату
FragmentPagerAdapter
должно быть использовано когда нам нужно сохранить фрагмент в памяти.когда я говорю, что весь фрагмент хранится в памяти, это означает, что его экземпляры не будут уничтожены и создадут накладные расходы памяти. Поэтому рекомендуется использовать
FragmentPagerAdapter
только при наличии малое количество фрагментов дляViewPager
.было бы еще лучше, если бы фрагменты были статическими, так как они не иметь большого количества объектов, экземпляры которых были бы на хранении.
более подробно,
FragmentStatePagerAdapter:
С
FragmentStatePagerAdapter
,ваш ненужный фрагмент разрушенный.Транзакция совершается для полного удаления фрагмент из вашей деятельностиFragmentManager
.государство
FragmentStatePagerAdapter
исходит из того, что он спасет ваш фрагментBundle
СsavedInstanceState
когда она уничтожена.Когда пользователь переходит назад,новый фрагмент будет восстановлено с использованием состояния фрагмента.
FragmentPagerAdapter:
по сравнению
FragmentPagerAdapter
ничего подобного.Когда фрагмент больше не нужен.FragmentPagerAdapter
вызовыdetach(Fragment)
на транзакция вместоremove(Fragment)
.это разрушает представление фрагмента, но оставляет экземпляр фрагмента живой в
FragmentManager
.Итак, фрагменты, созданные вFragmentPagerAdapter
никогда не уничтожаются.
что-то, что явно не сказано в документации или в ответах на этой странице (хотя и подразумевается @Naruto), это FragmentPagerAdapter
не будет обновлять фрагменты, если данные в фрагменте изменяется, потому что он держит фрагмент в памяти.
поэтому, даже если у вас есть ограниченное количество фрагментов для отображения, если вы хотите обновить свои фрагменты (например, вы повторно запустите запрос для обновления listView во фрагменте), вам нужно использовать FragmentStatePagerAdapter.
вся моя точка зрения здесь в том, что количество фрагментов и то, похожи они или нет, не всегда является ключевым аспектом для рассмотрения. Также важно, являются ли ваши фрагменты динамическими.
вот жизненный цикл журнала каждого фрагмента в 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
, которые имеют много страниц, потому что это будет хорошо для производительности.
пример of offscreenPageLimit
:
если мы пойдем в Fragment3, это будет detroy Fragment1 (или Fragment5, если есть), потому что offscreenPageLimit = 1
. Если мы установим offscreenPageLimit > 1
это не будет уничтожить.
Если в этом примере мы задаем offscreenPageLimit=4
, нет разницы между использованием FragmentStatePagerAdapter
или FragmentPagerAdapter
потому что фрагмент никогда не звонит onDestroyView
и onDestroy
когда мы меняем вкладке
FragmentPagerAdapter
хранит предыдущие данные, которые извлекаются из адаптера в то время как FragmentStatePagerAdapter
принимает новое значение от адаптера каждый раз, когда он выполняется.
FragmentStatePagerAdapter = для размещения большого количества фрагментов в ViewPager. Поскольку этот адаптер уничтожает фрагмент, когда он не виден пользователю и только savedInstanceState фрагмента сохраняется для дальнейшего использования. Таким образом, используется низкий объем памяти и улучшается производительность в случае динамических фрагментов.