提问者:小点点

使用ViewPager2获取当前片段


我将我的< code>ViewPager迁移到< code>ViewPager2,因为后者应该可以解决前者的所有问题。不幸的是,当它与< code > FragmentStateAdapter 一起使用时,我找不到任何方法来获取当前显示的片段。

viewPager.getCurrentItem()提供当前显示的索引,而adapter.getItem(index)Fragment。除非在getItem()中保留对所有创建片段的引用,否则我不知道如何访问当前显示的片段。

使用旧的ViewPager,一种解决方案是调用adapter.instantiateItem(index),它将返回所需索引处的片段。

我是否错过了ViewPager2


共2个答案

匿名用户

ViewPager2中,默认情况下,FragmentManager为片段分配了标签,如下所示:

第一个位置的片段具有标签< code >“F0”

第二个位置的片段有一个标签"f1"

第三个位置的片段有一个< code >“F2”标签,依此类推...所以你可以得到你的片段的标签,通过连接" f "和你的片段的位置。要获取当前片段,您可以从viewPager2位置获取当前位置,并使您的标记如下所示(对于Kotlin):

val myFragment = supportFragmentManager.findFragmentByTag("f" + viewpager.currentItem)

对于某一位置的碎片

val myFragment = supportFragmentManager.findFragmentByTag("f" + position)

如果使用此技术,可以强制转换片段并始终检查它是否不为 null。

如果您在 Fragment 中托管 ViewPager2,请改用 childFragmentManager

记得

如果您的适配器中有overridengetItemId(位置:Int)。那么你的情况不同。应该是:

val myFragment = supportFragmentManager.findFragmentByTag("f" + your_id_at_that_position)

或者简单地说:

val myFragment = supportFragmentManager.findFragmentByTag("f" + adapter.getItemId(position))

如果在Fragment中托管ViewPage2,请使用childFragmentManager而不是supportFragmentManager

匿名用户

通过标签查找当前片段的解决方案似乎最适合我。我为此创建了这些扩展函数:

fun ViewPager2.findCurrentFragment(fragmentManager: FragmentManager): Fragment? {
    return fragmentManager.findFragmentByTag("f$currentItem")
}

fun ViewPager2.findFragmentAtPosition(
    fragmentManager: FragmentManager,
    position: Int
): Fragment? {
    return fragmentManager.findFragmentByTag("f$position")
}
  • 如果您的 ViewPager2 主机是 Activity,请使用 supportFragmentManagerfragmentManager
  • 如果您的 ViewPager2 主机是 Fragment,请使用 childFragmentManager

注意:

  • findFragmentAtPosition仅适用于在ViewPager2的RecyclerView中初始化的碎片。因此,您只能获得可见的位置1。
  • Lint将建议您从fun ViewPager2.findFragmentAtPosition中删除ViewPager2.,因为您没有使用ViewPager2类中的任何内容。我认为它应该保持不变,因为这种变通方法只适用于ViewPager2