[英]Android: re-use fragments of ViewPager & FragmentPagerAdapter
[英]Android Lifecycle management of Fragments within ViewPager and FragmentPagerAdapter
我一直在努力找出使用ViewPager
在FragmentActivity
对Fragment的正确管理是什么。 在详细介绍之前,我将简要概述一下我所面临的问题:
我有一个带有ViewPager
的FragmentActivity
。 ViewPager
使用自定义但非常简单的FragmentPagerAdapter
。 ViewPager
每个Fragment
都包含一个ExpandableListView
。 我还有一个名为“刷新”的操作栏按钮。 现在,让我们假设ViewPager
只有一个Fragment
。 创建活动,并填充Fragment
的ExpandableListView
(到目前为止非常好)。 单击“刷新”按钮时, FragmentActivity
的处理方法将遍历分配给FragmentPagerAdapter的Fragments
列表,并在每个Fragment
上调用refresh()
以填充其ListView。 但是,当设备的方向发生变化(例如,从纵向变为横向)时,将重新创建“活动”,并且也会重新创建片段。 现在单击“刷新”按钮将遍历未初始化的Fragments
。
我知道我很模糊,尤其是没有示例代码时,但是请耐心等待。 从应用程序/活动的开始,我已经跟踪了以下问题和方法调用:
FragmentActivity.onCreate()
FragmentActivity.setContentView()
FragmentActivity.createPagerFragments()
<-这将创建一个ArrayList of Fragments,并将它们分配给新的FragmentPagerAdapter,后者又分配给ViewPager。 Fragment.onAttach()
Fragment.onCreate()
<-在这里没什么特别的,只是调用super方法。 Fragment.onCreateView()
<-这里也没有什么特别的,只是扩大了布局 Fragment.onActivityCreated()
<-在这里也没有。 FragmentActivity.onCreate()
Fragment.onAttach()
Fragment.onCreate()
FragmentActivity.setContentView()
FragmentActivity.createPagerFragments()
Fragment.onCreateView()
Fragment.onActivityCreated()
FragmentActivity.refresh()
<-迭代#13上新创建的片段(Android不能使用这些片段!)。 因此,我所看到的问题如下:当Android在更改屏幕方向后重新创建FragmentActivity
及其Views
(上面的调用#9-15),它将创建新的Fragment
对象,其状态恢复为原来的。 但是,这些似乎完全由FragmentManager
而不是FragmentPagerAdapter
。 相反,当FragmentPagerAdapter
与沿重新创建Fragments
在活动的onCreate
方法(见调用#13)的Fragments
是那些获得分配给适配器永远不会有自己的Fragment.onCreate()
或Fragment.onCreateView()
称为在方法所有。 因此,当调用refresh()方法(请参阅#17)时,该方法将对这些尚未初始化的Fragments
迭代。 因此,当他们尝试填充ExpandableListView
,视图的实例变量为NULL
。 这是可以预期的,因为实例变量仅在Fragment.onCreateView()
方法中分配,而该从来没有在这些Fragments
上调用。
所以我的问题是:如何改变屏幕方向后如何正确使用重新创建的(由Android生成的) Fragments
,以避免创建未初始化的Fragments
? 我需要对它们有一个有效的引用,以便调用按需填充它们的refresh()方法。 理想情况下,也应该将它们也分配给FragmentPagerAdapter
。
我希望我已经清楚地描述了这个问题,而我之所以没有提供示例代码,是因为问题(可以看出)不是源于代码本身,而是源于片段的相当不正确(重新移植)的创建而不是重复使用。 但是如果需要,我可以给您示例代码,通过这种方式我会更清楚。
谢谢!
要阅读很多东西,但是在阅读完简介和问题并具有FragmentStatePagerAdapter的经验之后,我类似于FragmentPagerAdapter可以告诉您:
旋转后,适配器将自动附着旧碎片。 因此看来,尽管正在重新创建活动创建适配器,但全局的FragmentManager和实例保留活动的重新创建将检测到新的FragmentStatePagerAdapter与相同的ViewPager组合在一起并请求相同的Fragments,并且只需从Fragment的BackStack中获取它们即可。
作为Fragments的设计者,您可以通过继续调用Fragment.onAttach()和Fragment.onDetach()来注意到此行为。 发生onAttach()时,要么创建您的Fragment,要么在旋转后重新使用它。 您应该能够通过使用回调onRestoreRnstanceState()来区分Fragment是旋转的。
您将在日志中同时看到许多onCreate()和其他状态日志,因为FragmentStatePagerAdapter总是获取/创建最少3个片段(除非您将它们设置为2或1),因此在屏幕旋转后,还会从中重新附加3个片段后栈。
希望对您有所帮助。
我相信这个问题 ,有关检索从ViewPager当前片段,会帮助你。 如前所述,片段由Fragment(State)PagerAdapter和NOT Activity或Fragment的生命周期管理。
getItem
方法将返回片段。 即使重新创建活动,每个片段仅调用一次此方法。 instantiateItem
方法返回。 很可能是在这里,您需要掌握片段并调用其刷新方法。 如何将其添加到清单中的“活动代码”中:
android:configChanges="orientation"
或API 13以上的版本
android:configChanges="orientation|screenSize"
因此当它改变方向时,它不会重新创建您的片段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.