What is the difference between FragmentPagerAdapter
and FragmentStatePagerAdapter
?
About FragmentPagerAdapter
Google's guide says:
This version of the pager is best for use when there are a handful of typically more static fragments to be paged through, such as a set of tabs. The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible. This can result in using a significant amount of memory since fragment instances can hold on to an arbitrary amount of state. For larger sets of pages, consider
FragmentStatePagerAdapter
.
And about FragmentStatePagerAdapter
:
This version of the pager is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment. This allows the pager to hold on to much less memory associated with each visited page as compared to
FragmentPagerAdapter
at the cost of potentially more overhead when switching between pages.
So I have just 3 fragments. But all of them are separate modules with a large amount of data.
Fragment1
handles some data (which users enter) and passes it via activity into Fragment2
, which is just a simple ListFragment
. Fragment3
is also a ListFragment
.
So my questions are: Which adapter should I use? FragmentPagerAdapter
or FragmentStatePagerAdapter
?
This question is related to
android
android-fragments
android-viewpager
fragmentpageradapter
fragmentstatepageradapter
FragmentStatePagerAdapter = To accommodate a large number of fragments in ViewPager. As this adapter destroys the fragment when it is not visible to the user and only savedInstanceState of the fragment is kept for further use. This way a low amount of memory is used and a better performance is delivered in case of dynamic fragments.
Here is a log lifecycle of each fragment in ViewPager
which have 4 fragment and offscreenPageLimit = 1 (default value)
FragmentStatePagerAdapter
Go to Fragment1 (launch activity)
Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart
Go to Fragment2
Fragment3: onCreateView
Fragment3: onStart
Go to Fragment3
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach
Fragment4: onCreateView
Fragment4: onStart
Go to Fragment4
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
FragmentPagerAdapter
Go to Fragment1 (launch activity)
Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart
Go to Fragment2
Fragment3: onCreateView
Fragment3: onStart
Go to Fragment3
Fragment1: onStop
Fragment1: onDestroyView
Fragment4: onCreateView
Fragment4: onStart
Go to Fragment4
Fragment2: onStop
Fragment2: onDestroyView
Conclusion: FragmentStatePagerAdapter
call onDestroy
when the Fragment is overcome offscreenPageLimit
while FragmentPagerAdapter
not.
Note: I think we should use FragmentStatePagerAdapter
for a ViewPager
which have a lot of page because it will good for performance.
Example of offscreenPageLimit
:
If we go to Fragment3, it will detroy Fragment1 (or Fragment5 if have) because offscreenPageLimit = 1
. If we set offscreenPageLimit > 1
it will not destroy.
If in this example, we set offscreenPageLimit=4
, there is no different between using FragmentStatePagerAdapter
or FragmentPagerAdapter
because Fragment never call onDestroyView
and onDestroy
when we change tab
Something that is not explicitly said in the documentation or in the answers on this page (even though implied by @Naruto), is that FragmentPagerAdapter
will not update the Fragments if the data in the Fragment changes because it keeps the Fragment in memory.
So even if you have a limited number of Fragments to display, if you want to be able to refresh your fragments (say for example you re-run the query to update the listView in the Fragment), you need to use FragmentStatePagerAdapter.
My whole point here is that the number of Fragments and whether or not they are similar is not always the key aspect to consider. Whether or not your fragments are dynamic is also key.
FragmentPagerAdapter: the fragment of each page the user visits will be stored in memory, although the view will be destroyed. So when the page is visible again, the view will be recreated but the fragment instance is not recreated. This can result in a significant amount of memory being used. FragmentPagerAdapter should be used when we need to store the whole fragment in memory. FragmentPagerAdapter calls detach(Fragment) on the transaction instead of remove(Fragment).
FragmentStatePagerAdapter: the fragment instance is destroyed when it is not visible to the User, except the saved state of the fragment. This results in using only a small amount of Memory and can be useful for handling larger data sets. Should be used when we have to use dynamic fragments, like fragments with widgets, as their data could be stored in the savedInstanceState.Also it won’t affect the performance even if there are large number of fragments.
FragmentPagerAdapter
stores the previous data which is fetched from the adapter while FragmentStatePagerAdapter
takes the new value from the adapter everytime it is executed.
FragmentStatePagerAdapter:
with FragmentStatePagerAdapter
,your unneeded fragment is
destroyed.A transaction is committed to completely remove the
fragment from your activity's FragmentManager
.
The state in FragmentStatePagerAdapter
comes from the fact that it
will save out your fragment's Bundle
from savedInstanceState
when
it is destroyed.When the user navigates back,the new fragment will be
restored using the fragment's state.
FragmentPagerAdapter:
By comparision FragmentPagerAdapter
does nothing of the kind.When
the fragment is no longer needed.FragmentPagerAdapter
calls
detach(Fragment)
on the transaction instead of remove(Fragment)
.
This destroy's the fragment's view but leaves the fragment's instance
alive in the FragmentManager
.so the fragments created in the
FragmentPagerAdapter
are never destroyed.
Source: Stackoverflow.com