我将我的< code>ViewPager迁移到< code>ViewPager2,因为后者应该可以解决前者的所有问题。不幸的是,当它与< code > FragmentStateAdapter 一起使用时,我找不到任何方法来获取当前显示的片段。
viewPager.getCurrentItem()
提供当前显示的索引,而adapter.getItem(index)
Fragment。除非在getItem()
中保留对所有创建片段的引用,否则我不知道如何访问当前显示的片段。
使用旧的ViewPager
,一种解决方案是调用adapter.instantiateItem(index),
它将返回所需索引处的片段。
我是否错过了ViewPager2
?
在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
。
记得
如果您的适配器中有overriden
的getItemId(位置: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")
}
Activity
,请使用 supportFragmentManager
或 fragmentManager
。Fragment
,请使用 childFragmentManager
注意:
findFragmentAtPosition
仅适用于在ViewPager2的RecyclerView中初始化的碎片。因此,您只能获得可见的位置1。fun ViewPager2.findFragmentAtPosition
中删除ViewPager2.
,因为您没有使用ViewPager2类中的任何内容。我认为它应该保持不变,因为这种变通方法只适用于ViewPager2