本文翻译自:What is the difference between FragmentPagerAdapter and FragmentStatePagerAdapter?
What is the difference between FragmentPagerAdapter
and FragmentStatePagerAdapter
? FragmentPagerAdapter
和FragmentStatePagerAdapter
什么区别?
About FragmentPagerAdapter
Google's guide says: 关于FragmentPagerAdapter
Google的指南说:
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
. 对于较大的页面集,请考虑FragmentStatePagerAdapter
。
And about FragmentStatePagerAdapter
: 关于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. 与FragmentPagerAdapter
相比,这允许寻呼机保持与每个被访问页面相关联的更少的存储器,代价是在页面之间切换时可能具有更多的开销。
So I have just 3 fragments. 所以我只有3个片段。 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
. Fragment1
处理一些数据(用户输入)并通过活动将其传递到Fragment2
,这只是一个简单的ListFragment
。 Fragment3
is also a ListFragment
. Fragment3
也是一个ListFragment
。
So my questions are : Which adapter should I use? 所以我的问题是 :我应该使用哪个适配器? FragmentPagerAdapter
or FragmentStatePagerAdapter
? FragmentPagerAdapter
还是FragmentStatePagerAdapter
?
#1楼
参考:https://stackoom.com/question/1GfCh/FragmentPagerAdapter和FragmentStatePagerAdapter有什么区别
#2楼
Like the docs say, think about it this way. 就像文档说的那样,以这种方式思考。 If you were to do an application like a book reader, you will not want to load all the fragments into memory at once. 如果您要像书阅读器那样执行应用程序,则不希望一次将所有片段加载到内存中。 You would like to load and destroy Fragments
as the user reads. 您希望在用户阅读时加载和销毁Fragments
。 In this case you will use FragmentStatePagerAdapter
. 在这种情况下,您将使用FragmentStatePagerAdapter
。 If you are just displaying 3 "tabs" that do not contain a lot of heavy data (like Bitmaps
), then FragmentPagerAdapter
might suit you well. 如果您只是显示3个不包含大量重量数据的“标签”(如Bitmaps
),那么FragmentPagerAdapter
可能很适合您。 Also, keep in mind that ViewPager
by default will load 3 fragments into memory. 另外,请记住, ViewPager
默认会将3个片段加载到内存中。 The first Adapter
you mention might destroy View
hierarchy and re load it when needed, the second Adapter
only saves the state of the Fragment
and completely destroys it, if the user then comes back to that page, the state is retrieved. 您提到的第一个Adapter
可能会破坏View
层次结构并在需要时重新加载它,第二个Adapter
仅保存Fragment
的状态并完全销毁它,如果用户然后返回该页面,则检索状态。
#3楼
FragmentPagerAdapter
stores the whole fragment in memory, and could increase a memory overhead if a large amount of fragments are used inViewPager
.FragmentPagerAdapter
将整个片段存储在内存中,如果在ViewPager
中使用了大量片段,则会增加内存开销。In contrary its sibling,
FragmentStatePagerAdapter
only stores the savedInstanceState of fragments, and destroys all the fragments when they lose focus. 与其兄弟相反,FragmentStatePagerAdapter
仅存储片段的savedInstanceState,并在失去焦点时销毁所有片段。Therefore
FragmentStatePagerAdapter
should be used when we have to use dynamic fragments, like fragments with widgets, as their data could be stored in thesavedInstanceState
.Also it wont affect the performance even if there are large number of fragments. 因此,当我们必须使用动态片段(如具有小部件的片段)时,应使用FragmentStatePagerAdapter
,因为它们的数据可以存储在savedInstanceState
。即使存在大量片段,它也不会影响性能。In contrary its sibling
FragmentPagerAdapter
should be used when we need to store the whole fragment in memory. 相反,当我们需要将整个片段存储在内存中时,应该使用它的兄弟FragmentPagerAdapter
。When I say the whole fragment is kept in memory it means, its instances wont be destroyed and would create a memory overhead. 当我说整个片段保存在内存中意味着,它的实例不会被破坏并且会产生内存开销。 Therefore it is advised to use
FragmentPagerAdapter
only when there are low number of fragments forViewPager
. 因此,建议仅在ViewPager
的片段数较少时才使用FragmentPagerAdapter
。It would be even better if the fragments are static, since they would not be having large amount of objects whose instances would be stored. 如果片段是静态的,那将会更好,因为它们不会有大量的实例存储的对象。
To be more detail, 更详细一点,
FragmentStatePagerAdapter: FragmentStatePagerAdapter:
with
FragmentStatePagerAdapter
,your unneeded fragment is destroyed.A transaction is committed to completely remove the fragment from your activity'sFragmentManager
. 使用FragmentStatePagerAdapter
,您的不需要的片段将被销毁。事务将被提交以从您的活动的FragmentManager
完全删除该片段。The state in
FragmentStatePagerAdapter
comes from the fact that it will save out your fragment'sBundle
fromsavedInstanceState
when it is destroyed.When the user navigates back,the new fragment will be restored using the fragment's state.FragmentStatePagerAdapter
的状态来自这样一个事实:当它被销毁时,它会从savedInstanceState
保存你的片段的Bundle
。当用户导航回来时,将使用片段的状态恢复新的片段。
FragmentPagerAdapter: FragmentPagerAdapter:
By comparision
FragmentPagerAdapter
does nothing of the kind.When the fragment is no longer needed. 通过比较FragmentPagerAdapter
什么都不做。当不再需要片段时。FragmentPagerAdapter
callsdetach(Fragment)
on the transaction instead ofremove(Fragment)
.FragmentPagerAdapter
调用事务上的detach(Fragment)
而不是remove(Fragment)
。This destroy's the fragment's view but leaves the fragment's instance alive in the
FragmentManager
.so the fragments created in theFragmentPagerAdapter
are never destroyed. 这种破坏是片段的观点,但离开片段的实例活着的FragmentManager
。所以在创建的片段FragmentPagerAdapter
永远不会被销毁。
#4楼
FragmentPagerAdapter
存储从适配器获取的先前数据,而FragmentStatePagerAdapter
每次执行时都从适配器获取新值。
#5楼
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. 文档或本页答案中未明确说明的内容(即使@Naruto暗示),如果Fragment中的数据发生更改, FragmentPagerAdapter
将不会更新Fragments,因为它会将Fragment保留在内存中。
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. 因此,即使您要显示有限数量的片段,如果您希望能够刷新片段(例如,重新运行查询以更新片段中的listView),则需要使用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. 您的碎片是否是动态的也是关键。
#6楼
FragmentStatePagerAdapter = To accommodate a large number of fragments in ViewPager. FragmentStatePagerAdapter =在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. 由于此适配器在用户不可见时销毁该片段,并且仅保留片段的savedInstanceState以供进一步使用。 This way a low amount of memory is used and a better performance is delivered in case of dynamic fragments. 这样,使用少量内存,并且在动态片段的情况下提供更好的性能。