我有一个Fragment(我称之为pagerFragment
),它被添加到backstack中并且是可见的,它包含一个viewPager
和一个FragmentPagerAdapter
,FragmentPagerAdapter
包含(比方说)两个fragment:A和B
第一次添加片段效果很好。
片段A有一个按钮,一旦被点击,就会将一个片段(C)添加到backstack。
问题是这样的:如果添加片段(C),然后单击Back,则pagerAdapter
为空,且看不到其中任何片段。
如果我使用一个hack,并销毁pagerFragment
s onDestroyView()
中的子片段(A和B),这就解决了问题,尽管我不想不使用这个hack。
你知道是什么问题吗?
5条答案
按热度按时间62o28rlo1#
我也遇到了同样的问题。我的解决办法很简单:
在onCreateView中,我有:
其中,SectionPageAdapter类似于以下内容:
将getSupportFragmentManager更改为
它开始工作了!
vawmfj5a2#
由于ViewPager位于PagerFragment内部,因此听起来像是使用了嵌套片段。是否已将getChildFragmentManager()传递给FragmentPagerAdapter的构造函数?如果未传递,则应传递。
我不认为你需要一个FragmentStatePagerAdapter,但我会给它一个机会,因为它处理保存和恢复片段状态.事实上,你的onDestroyView()破解工作让我认为你可能需要一个FragmentStatePagerAdapter.
这也可能与FragmentPagerAdapter添加片段的方式有关。FragmentPagerAdapter不会将片段添加到backstack。想象一下,如果你在ViewPager中添加了10多个页面,用户在其中滑动。用户需要点击11次才能退出应用程序。
也可能和这个帖子有关:Nested Fragments and The Back Stack.
我也不确定你要把C片段加到什么地方。你是把它加到和ViewPager相同的容器里吗?
好吧,至少你有几个选项可以研究。在这种情况下,我喜欢调试Android SDK源代码,看看是什么导致了这种行为。我建议抓住AOSP source,并添加frameworks/support和frameworks/base作为SDK源代码。这是了解正在发生的事情并避免在事情正常工作之前进行随机更改的唯一真正方法。
mlnl4t2r3#
使用
getChildFragmentManager()
代替getSupportFragmentManager()
,它会工作得很好。cgh8pdjw4#
我在我们的项目中也遇到了这个问题,根本原因是FragmentPagerAdapter的工作方式:
FragmentPagerAdapter只是从其视图中分离他当前不需要的片段,但不从其FragmentManager中移除该片段。当他想要再次显示该片段时,他使用从ViewPager的视图id和适配器getItemId返回的id创建的标记来查看FragmentManager是否仍然包含该片段(position)调用。如果他找到了一个片段,他就在FragmentManager的更新事务中调度一个片段到它的视图的附加。只有当他没有找到一个片段时,他才使用适配器getItem(position)调用创建一个新的片段!
包含具有FragmentPagerAdapter的ViewPager的Fragment的问题在于,将包含Fragment的FragmentManager放入后台堆栈时,FragmentManager的内容永远不会清除。如果包含Fragment从后台堆栈返回,它将创建新视图,但FragmentManager仍包含附加到旧视图的片段,并且现有片段的附加不再起作用。
解决这个问题最简单的方法是避免嵌套片段。:)
第二个最简单的方法是,正如在其他文章中提到的,使用ChildFragmentManager作为FragmentPagerAdapter,因为它在容器片段的生命周期中会得到正确的更新。
由于有些项目(如我目前的项目)两种选择都不可行,我在这里发布了一个解决方案,它可以使用任意的FragmentManager,方法是使用子片段的hashCode作为该位置片段的项id,其代价是在适配器中存储所有位置的所有片段。
}
cunj1qz15#
示例代码: