FragmentPagerAdapter和FragmentStatePagerAdapter的区别是什么?

关于FragmentPagerAdapter谷歌的指南说:

此版本的寻呼机最适合在有少量 通常需要分页更多的静态片段,例如一组 选项卡。用户访问的每个页面的片段将被保留 内存,尽管它的视图层次结构可能在不可见时被破坏。 这可能导致使用大量的内存,因为片段 实例可以保留任意数量的状态。对于较大的电视机 ,考虑FragmentStatePagerAdapter。

关于FragmentStatePagerAdapter:

这个版本的寻呼机在有大量数据时更有用 页面,工作起来更像一个列表视图。当页面不可见时 对用户来说,他们的整个碎片可能被销毁,只保留了 该片段的保存状态。这使得寻呼机可以保留很多信息 与。相比,与每个访问页面关联的内存更少 FragmentPagerAdapter以潜在的更多开销为代价 在页面之间切换。

所以我只有3个片段。但它们都是包含大量数据的独立模块。

Fragment1处理一些数据(用户输入的),并通过活动将其传递给Fragment2,这只是一个简单的ListFragment。Fragment3也是一个ListFragment。

所以我的问题是:我应该使用哪个适配器?FragmentPagerAdapter还是FragmentStatePagerAdapter?


当前回答

下面是ViewPager中每个片段的日志生命周期,其中有4个片段,offscreenPageLimit = 1(默认值)

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在Fragment被offscreenPageLimit克服时调用onDestroy,而FragmentPagerAdapter没有。

注意:我认为我们应该使用FragmentStatePagerAdapter的ViewPager有很多页面,因为这将有利于性能。

offscreenPageLimit的示例:

如果我们转到Fragment3,它将破坏Fragment1(或者Fragment5),因为offscreenPageLimit = 1。如果我们设置offscreenPageLimit > 1,它不会破坏。 如果在这个例子中,我们设置offscreenPageLimit=4,使用FragmentStatePagerAdapter和FragmentPagerAdapter之间没有区别,因为当我们改变制表符时,Fragment从不调用onDestroyView和onDestroy

Github演示在这里

其他回答

在文档或本页的答案中没有明确说明的事情(即使由@Naruto暗示)是,FragmentPagerAdapter将不会更新片段,如果片段中的数据发生变化,因为它将片段保存在内存中。

所以即使你有有限数量的片段显示,如果你想要能够刷新你的片段(例如你重新运行查询来更新片段中的listView),你需要使用FragmentStatePagerAdapter。

我在这里的全部观点是,片段的数量以及它们是否相似并不总是需要考虑的关键方面。你的片段是否是动态的也是关键。

FragmentStatePagerAdapter =在ViewPager中容纳大量的片段。当片段对用户不可见时,这个适配器会销毁它,并且只保留片段的savedInstanceState以供进一步使用。在动态片段的情况下,这样可以使用较少的内存并提供更好的性能。

下面是ViewPager中每个片段的日志生命周期,其中有4个片段,offscreenPageLimit = 1(默认值)

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在Fragment被offscreenPageLimit克服时调用onDestroy,而FragmentPagerAdapter没有。

注意:我认为我们应该使用FragmentStatePagerAdapter的ViewPager有很多页面,因为这将有利于性能。

offscreenPageLimit的示例:

如果我们转到Fragment3,它将破坏Fragment1(或者Fragment5),因为offscreenPageLimit = 1。如果我们设置offscreenPageLimit > 1,它不会破坏。 如果在这个例子中,我们设置offscreenPageLimit=4,使用FragmentStatePagerAdapter和FragmentPagerAdapter之间没有区别,因为当我们改变制表符时,Fragment从不调用onDestroyView和onDestroy

Github演示在这里

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. In this case you will use 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. Also, keep in mind that ViewPager by default will load 3 fragments into memory. 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.

FragmentPagerAdapter存储以前从适配器获取的数据,而FragmentStatePagerAdapter每次执行时都从适配器获取新值。