FragmentPagerAdapter和FragmentStatePagerAdapter的区别是什么?

关于FragmentPagerAdapter谷歌的指南说:

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

关于FragmentStatePagerAdapter:

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

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

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

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


当前回答

医生说:

有两种类型的标准pageradapter管理每个片段的生命周期:FragmentPagerAdapter和FragmentStatePagerAdapter。它们都能很好地处理片段,但它们更适合不同的场景:

The FragmentPagerAdapter stores the fragments in memory as long as the user can navigate between them. When a fragment is not visible, the PagerAdapter will detach it, but not destroy it, so the fragment instance remains alive in the FragmentManager. It will release it from memory only when the Activity shuts down. This can make the transition between pages fast and smooth, but it could cause memory issues in your app if you need many fragments. The FragmentStatePagerAdapter makes sure to destroy all the fragments the user does not see and only keep their saved states in the FragmentManager, hence the name. When the user navigates back to a fragment, it will restore it using the saved state. This PagerAdapter requires much less memory, but the process of switching between pages can be slower.

其他回答

不知道技术细节,但根据我的经验: 如果你尝试在一个片段中的viewPager中使用FragmentStatePagerAdapter,那么你的子片段的选项菜单可能会被搞砸(或者根本不显示),如果你导航到另一个页面并返回。但是它将与FragmentPagerAdapter一起工作。 据我所知,在用户单击一个选项卡之前,子片段的onCreateOptionsMenu没有被调用。这可能是有意的,但对我来说是一场噩梦。

在毫无希望的搜索中,我偶然发现了一些页面: https://issuetracker.google.com/issues/37092407 Viewpager片段的选项菜单显示彼此的按钮 嵌套片段在viewpager与不同的菜单

PS:任何使用FragmentStatePagerAdapter的优雅解决方案或建议都是受欢迎的

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.

FragmentStatePagerAdapter:

使用FragmentStatePagerAdapter,您不需要的片段是 摧毁。事务提交时完全删除 fragment从你的活动的FragmentManager。 FragmentStatePagerAdapter中的状态来自于它 将从savedInstanceState保存你的片段的Bundle什么时候 它被摧毁了。当用户导航回来时,新的片段将是 使用片段的状态恢复。

FragmentPagerAdapter:

相比之下,FragmentPagerAdapter什么也不做。当 不再需要这个片段。FragmentPagerAdapter调用 detach(Fragment)而不是remove(Fragment)。 这个destroy是片段的视图,但留下了片段的实例 在FragmentManager中存活。创建的片段 FragmentPagerAdapter永远不会被销毁。

医生说:

有两种类型的标准pageradapter管理每个片段的生命周期:FragmentPagerAdapter和FragmentStatePagerAdapter。它们都能很好地处理片段,但它们更适合不同的场景:

The FragmentPagerAdapter stores the fragments in memory as long as the user can navigate between them. When a fragment is not visible, the PagerAdapter will detach it, but not destroy it, so the fragment instance remains alive in the FragmentManager. It will release it from memory only when the Activity shuts down. This can make the transition between pages fast and smooth, but it could cause memory issues in your app if you need many fragments. The FragmentStatePagerAdapter makes sure to destroy all the fragments the user does not see and only keep their saved states in the FragmentManager, hence the name. When the user navigates back to a fragment, it will restore it using the saved state. This PagerAdapter requires much less memory, but the process of switching between pages can be slower.

FragmentPagerAdapter:用户访问的每个页面的片段将存储在内存中,尽管视图将被销毁。因此,当页面再次可见时,视图将被重新创建,但片段实例不会被重新创建。这可能会导致占用大量内存。当我们需要在内存中存储整个片段时,应该使用FragmentPagerAdapter。FragmentPagerAdapter在事务上调用detach(Fragment)而不是remove(Fragment)。

FragmentStatePagerAdapter:当片段实例对用户不可见时销毁,除了保存的片段状态。这导致只使用少量的内存,对于处理较大的数据集非常有用。当我们必须使用动态片段时应该使用,比如带有小部件的片段,因为它们的数据可以存储在savedInstanceState中。而且即使有大量的片段也不会影响性能。