添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

FragmentPagerAdapter和FragmentStatePagerAdapter之间有什么区别?

403 人关注

替换代码0】和 FragmentStatePagerAdapter 之间有什么区别?

关于【替换代码0谷歌的指南说。

这个版本的寻呼机最适合在有少量典型的静态片段需要寻呼时使用。 通常更多的静态片段要被分页,比如一组 标签。用户访问的每个页面的片段都会被保留在内存中 内存中,尽管它的视图层次结构在不可见时可能会被销毁。 这可能会导致使用大量的内存,因为片段 实例可以保留任意数量的状态。对于更大的页面集 的页面,请考虑 FragmentStatePagerAdapter

And about FragmentStatePagerAdapter :

当有大量的页面时,这个版本的寻呼机更有用。 的时候更有用,工作起来更像一个列表视图。当页面对用户不可见时 时,他们的整个片段可能被销毁,只保留该片段的 保存的那个片段的状态。这使得寻呼机在访问每个页面时,可以保留更多的 相比之下,与每个被访问的页面相关的内存要少得多。 替换代码0】的代价是,在页面之间切换时可能会有更多的开销。 在页面之间切换时可能会有更多的开销。

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

替换代码6】处理一些数据(用户输入的),并通过活动将其传递给 Fragment2 ,后者只是一个简单的 ListFragment Fragment3 也是一个 ListFragment

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

4 个评论
我认为只有3个Fragments使你有资格使用FragmentPagerAdapter。 这些片段的标签可能都会同时可见。
这个帖子救了我5-6个小时,因为我使用了错误的适配器类型。
对这个问题的回答又抛出了一个问题 stackoverflow.com/questions/9156406/...
there is FragmentPagerAdapter and FragmentStatePagerAdapter but what is FragmentStateAdapter ?
android
android-fragments
android-viewpager
fragmentpageradapter
fragmentstatepageradapter
AlexMomotov
AlexMomotov
发布于 2013-09-12
9 个回答
Emmanuel
Emmanuel
发布于 2022-11-09
已采纳
0 人赞同

就像文档中说的,这样想吧。如果你要做一个像图书阅读器那样的应用,你不会想一次就把所有的片段加载到内存中。你会希望在用户阅读时加载和销毁 Fragments 。在这种情况下,你将使用 FragmentStatePagerAdapter 。如果你只是显示3个不包含大量沉重数据的 "标签"(如 Bitmaps ),那么 FragmentPagerAdapter 可能很适合你。另外,请记住, ViewPager 在默认情况下会加载3个片段到内存中。你提到的第一个 Adapter 可能会破坏 View 的层次结构,并在需要时重新加载它。第二个 Adapter 只保存 Fragment 的状态,并完全销毁它,如果用户再回到那个页面,状态就会被找回来。

我在Fragment1和ListView中有多个按钮和TextViews,它们在Fragment2和Fragment3中动态地生成项目。你认为使用FragmentStatePagerAdapter并在Activity中存储所有数据,通过Bundle将其传递给Fragments是一个好主意吗?
@AlexMomotov Fragment的布局中的视图与FragmentStatePagerAdapter的选择没有任何关系。 这里的问题是将被分页的Fragments的数量。
所以,基本上没有什么有利于 FragmentPagerAdapter 的使用。
@Tomasz FragmentPagerAdapter 的好处是,在片段之间的切换可以快得多,因为实际的 Fragment 对象不需要每次都被重建。另一方面,这将最终使用更多的内存来保存内存中的片段对象。
我有3个标签/页面(每个都显示一个WebView),所以使用了 碎片化页面适配器(FragmentPagerAdapter .然而,当我从第一页扫过时,最后一页仍然被重绘。为了解决这个问题,我使用了 viewPager.setOffscreenPageLimit(2)
Steve
Steve
发布于 2022-11-09
0 人赞同

FragmentStatePagerAdapter:

  • FragmentStatePagerAdapter ,你不需要的片段会被销毁。 一个事务被提交以从你的活动的 FragmentManager 中完全删除该片段。 从你的活动的 FragmentManager 中删除片段。

  • FragmentStatePagerAdapter 中的状态来自于以下事实 当它被销毁时,它将从 savedInstanceState 中保存出你的片段的 Bundle 。 当用户导航回来时,新的片段将使用该片段的状态被恢复。 当用户返回时,新的片段将使用该片段的状态被恢复。

    FragmentPagerAdapter:

  • 相比之下, FragmentPagerAdapter 没有做任何事情。 片段不再需要时, FragmentPagerAdapter 调用 detach(Fragment) ,而不是 remove(Fragment)

  • 这就破坏了片段的视图,但在 FragmentManager 中保留了片段的实例。 所以在 FragmentManager 中创建的片段不会被销毁。 替换代码5】中创建的片段不会被销毁。

  • 为什么你有两个答案?
    将整个片段保留在内存中的好处是什么?
    @Tomek : 如果下一个片段已经实例化了(即FragmentPagerAdapter),当你刷到它时,它将准备好渲染,所以刷屏动画会更流畅。对于FragmentStatePagerAdapter,下一个片段实例可能在你刷到它之前不存在,如果它是一个大的片段,创建成本很高,你可能会在动画中看到一个停顿。这是一个性能与内存消耗的问题。
    @Jared Burrows bcoz one is just 答复文本 这对小的和静态的答案很好,另一个是 回答状态文本 这是为更大的和动态的答案
    Linh
    Linh
    发布于 2022-11-09
    0 人赞同

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

    片段状态查询器Adapter

    转到片段1(启动活动)。

    Fragment1: onCreateView
    Fragment1: onStart
    Fragment2: onCreateView
    Fragment2: onStart
    

    转到片段2

    Fragment3: onCreateView
    Fragment3: onStart
    

    转到片段3

    Fragment1: onStop
    Fragment1: onDestroyView
    Fragment1: onDestroy
    Fragment1: onDetach
    Fragment4: onCreateView
    Fragment4: onStart
    

    转到片段4

    Fragment2: onStop
    Fragment2: onDestroyView
    Fragment2: onDestroy
    

    碎片化页面适配器(FragmentPagerAdapter

    转到片段1(启动活动)。

    Fragment1: onCreateView
    Fragment1: onStart
    Fragment2: onCreateView
    Fragment2: onStart
    

    转到片段2

    Fragment3: onCreateView
    Fragment3: onStart
    

    转到片段3

    Fragment1: onStop
    Fragment1: onDestroyView
    Fragment4: onCreateView
    Fragment4: onStart
    

    转到片段4

    Fragment2: onStop
    Fragment2: onDestroyView
    

    Conclusion: FragmentStatePagerAdapter call onDestroy when the Fragment is overcome offscreenPageLimit while FragmentPagerAdapter not.

    Note:我认为我们应该对有大量页面的ViewPager使用FragmentStatePagerAdapter,因为这对性能有好处。

    例子 of offscreenPageLimit:

    如果我们去看Fragment3,它will破坏Fragment1(或Fragment5,如果有的话),因为offscreenPageLimit = 1。如果我们设置offscreenPageLimit > 1,它will not destroy.
    如果在这个例子中,我们设置了offscreenPageLimit=4,那么使用FragmentStatePagerAdapterFragmentPagerAdapter并没有什么不同,因为当我们改变标签时,Fragment绝不会调用onDestroyViewonDestroy

    Github demo here

    这样的结论方式很好!
    很好的解释
    很好的解释。你说当有很多页的时候,使用FragmentStatePagerAdapter对性能有好处。你的意思是它对节省内存有好处吗?我理解的目标是在可能有很多Fragment实例的情况下保存内存--所以性能是隐含的好处;明确的目标是保存内存。
    JDenais
    JDenais
    发布于 2022-11-09
    0 人赞同

    一些在文档和本页答案中没有明确说到的东西(尽管@Naruto暗示了),就是 FragmentPagerAdapter 不会在片段中的数据发生变化时更新片段,因为它把片段保留在内存中。

    因此,即使你有数量有限的Fragments来显示,如果你想能够刷新你的Fragments(比如说你重新运行查询来更新Fragment中的listView),你需要使用FragmentStatePagerAdapter。

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

    Ced
    所以说我有2个片段,片段A中有1个recyclerview,当我点击一个项目时,它会改变片段B的内容,比如我做片段B.setText("blablabla")。那么我应该使用状态页面吗?
    不确定,但我想说是的。试一下这两种方法,反正把你的代码从一种改成另一种是非常容易和快速的。
    @JDenais 你确定这是对的吗?我在我的活动中使用 FragmentPagerAdapter ,该活动使用ViewPager来显示两个片段--其中每个片段包含一个列表。我的第一个列表被称为 "所有报告",第二个列表是 "最喜欢的报告"。在第一个列表中,如果我点击某个报告的星形图标,它就会更新数据库以切换该报告的最爱状态。然后我轻扫过去,我就能在第二个列表的用户界面中看到这个报告。因此,也许实例被保存在内存中,但在某些情况下(例如我的),内容实际上会对FragmentPagerAdapter进行正常更新
    vinay kumar
    vinay kumar
    发布于 2022-11-09
    0 人赞同

    替换代码0】存储从适配器获取的前一个数据,而 FragmentStatePagerAdapter 每次执行时都从适配器获取新的值。

    Ashish Dwivedi
    Ashish Dwivedi
    发布于 2022-11-09
    0 人赞同

    FragmentStatePagerAdapter = 为了在ViewPager中容纳大量的片段。因为这个适配器在用户不可见的时候会销毁片段,只有片段的保存状态(savedInstanceState)被保留下来供进一步使用。这样一来,在动态片段的情况下,就可以使用较少的内存并提供更好的性能。

    Foroogh Varmazyar
    Foroogh Varmazyar
    发布于 2022-11-09
    0 人赞同

    碎片化页面适配器(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).

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

    Sanam Yavarpor
    Sanam Yavarpor
    发布于 2022-11-09
    0 人赞同

    根据博士的说法。

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

  • FragmentPagerAdapter将片段存储在内存中,只要用户可以在它们之间浏览。当一个片段不可见时,PagerAdapter将分离它,但不销毁它,因此片段实例在FragmentManager中保持活力。它只有在Activity关闭时才会从内存中释放它。这可以使页面之间的过渡快速而平滑,但如果你需要很多片段,它可能会在你的应用程序中导致内存问题。

  • FragmentStatePagerAdapter确保销毁所有用户没有看到的片段,只在FragmentManager中保留它们的保存状态,因此而得名。当用户导航回到一个片段时,它将使用保存的状态恢复它。这个PagerAdapter需要的内存要少得多,但是在页面之间切换的过程会比较慢。

  • eddym
    eddym
    发布于 2022-11-09
    0 人赞同

    不知道技术细节,但根据我的经验。
    如果你试图在一个片段中的viewPager中使用 FragmentStatePagerAdapter ,那么你的子片段的选项菜单可能会被打乱(或者根本不显示),如果你导航到另一个页面并回来。但在 FragmentPagerAdapter 中,它可以工作。
    在我看来, onCreateOptionsMenu 的子片段在用户点击到一个标签之前不会被调用。这可能是故意的,但对我来说是个噩梦。