首页 文章

FragmentPagerAdapter和FragmentStatePagerAdapter有什么区别?

提问于
浏览
304

FragmentPagerAdapterFragmentStatePagerAdapter 有什么区别?

关于 FragmentPagerAdapter Google的指南说:

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

关于 FragmentStatePagerAdapter

当有大量页面时,此版本的寻呼机更有用,更像列表视图 . 当页面对用户不可见时,它们的整个片段可能会被破坏,只保留该片段的保存状态 . 与FragmentPagerAdapter相比,这允许寻呼机保持与每个被访问页面相关联的更少的存储器,代价是在页面之间切换时可能具有更多开销 .

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

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

So my questions are :我应该使用哪种适配器? FragmentPagerAdapterFragmentStatePagerAdapter

6 回答

  • 108
    • FragmentPagerAdapter 将整个片段存储在内存中,如果 ViewPager 中使用了大量片段,则会增加内存开销 .

    • 与其兄弟相反, FragmentStatePagerAdapter 仅存储片段的savedInstanceState,并在失去焦点时销毁所有片段 .

    • 因此,当我们必须使用动态片段(例如带有小部件的片段)时,应该使用 FragmentStatePagerAdapter ,因为它们的数据可以存储在_208166中 . 即使有大量片段,它也不会影响性能 .

    • 相反,当我们需要将整个片段存储在内存中时,应该使用它的兄弟 FragmentPagerAdapter .

    • 当我说整个片段保存在内存中意味着,它的实例不会被破坏并且会产生内存开销 . 因此,建议仅在 ViewPager 的片段数较少时才使用 FragmentPagerAdapter .

    • 如果片段是静态的,那将会更好,因为它们不会有大量的实例存储的对象 .

    更详细一点,

    FragmentStatePagerAdapter:

    • FragmentStatePagerAdapter ,您的不需要的片段被销毁 . 事务被提交以从您的活动的 FragmentManager 中完全删除该片段 .

    • FragmentStatePagerAdapter 中的状态来自这样一个事实:当它被销毁时,它将从 savedInstanceState 中保存你的片段 Bundle . 当用户导航回来时,将使用片段的状态恢复新片段 .

    FragmentPagerAdapter:

    • 通过比较 FragmentPagerAdapter 什么都不做 . 当片段不再需要时 . FragmentPagerAdapter 在事务上调用 detach(Fragment) 而不是 remove(Fragment) .

    • 这会破坏_208181的视图,但会将片段的实例保留在 FragmentManager 中 . 所以 FragmentPagerAdapter 中创建的片段永远不会被破坏 .

  • 12

    文档或本页答案中未明确说明的内容(即使@Naruto暗示),如果片段中的数据发生更改, FragmentPagerAdapter 将不会更新片段,因为它会将片段保留在内存中 .

    因此,即使您要显示有限数量的片段,如果您希望能够刷新片段(例如,重新运行查询以更新片段中的listView),则需要使用FragmentStatePagerAdapter .

    我的全部观点是,碎片的数量以及它们是否相似并不总是需要考虑的关键方面 . 您的碎片是否是动态的也是关键 .

  • 244

    FragmentPagerAdapter 存储从适配器获取的先前数据,而 FragmentStatePagerAdapter 在每次执行时从适配器获取新值 .

  • 30

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

  • 18

    就像文档说的那样,以这种方式思考它 . 如果您要执行类似书籍阅读器的应用程序,则不希望立即将所有片段加载到内存中 . 您希望在用户阅读时加载和销毁 Fragments . 在这种情况下,您将使用 FragmentStatePagerAdapter . 如果你只是显示3 "tabs"不包含大量重量数据(如 Bitmaps ),那么 FragmentPagerAdapter 可能很适合你 . 另外,请记住 ViewPager 默认情况下会将3个片段加载到内存中 . 您提到的第一个 Adapter 可能会破坏 View 层次结构并重新加载它在需要时,第二个 Adapter 仅保存 Fragment 的状态并完全销毁它,如果用户然后返回该页面,则检索状态 .

  • 2

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

    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
    

    ConclusionFragmentStatePagerAdapter 调用 onDestroy 时片段被克服 offscreenPageLimitFragmentPagerAdapter 没有 .

    Note :我认为我们应该将 FragmentStatePagerAdapter 用于 ViewPager ,它有很多页面,因为它有利于提高性能 .

    Example of offscreenPageLimit

    如果我们去Fragment3,它会 will detroy Fragment1(或者如果有Fragment5)因为 offscreenPageLimit = 1 . 如果我们设置 offscreenPageLimit > 1will not 摧毁 .
    如果在这个例子中,我们设置 offscreenPageLimit=4 ,则使用 FragmentStatePagerAdapterFragmentPagerAdapter 之间没有区别,因为当我们更改选项卡时,Fragment永远不会调用 onDestroyViewonDestroy

    Github demo here

相关问题