我的问题
根据谷歌的文档:
您现在可以在片段中嵌入片段。这对于您希望将动态且可重用的 UI 组件放入本身是动态且可重用的 UI 组件的各种情况很有用。例如,如果您使用 ViewPager 创建 向左和向右滑动并占用大部分屏幕空间的片段,您 现在可以将片段插入到每个片段页面中。要嵌套片段,只需在要添加片段的片段上调用 getChildFragmentManager()。这将返回一个 FragmentManager,您可以像通常从顶级活动中一样使用它来创建片段事务。例如,下面是一些从现有 Fragment 类中添加片段的代码:
Fragment videoFragment = new VideoPlayerFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.video_fragment, videoFragment).commit();
所以我创建了我自己的PageFragment
. 我的PageFragmentAdapter
由 3 页组成PageFragment
。我也有六个片段:Fragment1
, Fragment2
, Fragment3
, FragmentA
, FragmentB
, FragmentC
。在我的MainActivity
我初始化了我的六个片段,我的ViewPager
和它的PageFragmentAdapter
(它为自己初始化了三个PageFragment
)。
然后我使用这种方法将我的Fragment1
, Fragment2
,附加Fragment3
到每个页面(每个PageFragment
)PageFragmentAdapter
:
PageFragmentAdapter tPageFragmentAdapter = new PageFragmentAdapter(getSupportFragmentManager());
tPageFragmentAdapter.setFirstPage(tFragment1);
tPageFragmentAdapter.setSecondPage(tFragment2);
tPageFragmentAdapter.setThirdPage(tFragment3);
我可以接收(通过方法PageFragmentAdapter
)片段并将“嵌套片段”放入我PageFragment
的(当然是onCreate()
)中,例如:
getChildFragmentManager().beginTransaction()
.add(R.id.framelayout_history, mFragment)
.addToBackStack(null)
.commit();
注意:我PageFragment.setNestedFragment()
用来设置mFragment
它。
而且效果很好!它将帮助我(但这个故事不是关于它)简单地替换 ViewPager 中的片段,例如:
tPageFragmentAdapter.replaceFirstPage(tFragmentA);
但我有一个大问题。再次谷歌的文档:
PagerAdapter 的实现,它将每个页面表示为一个 Fragment,只要用户可以返回该页面,它就会永久保存在 Fragment 管理器中。此版本的分页器最适合在需要分页的情况下使用少数通常更静态的片段,例如一组选项卡。用户访问的每个页面的片段都 将保存在内存中,尽管它的视图层次结构 在不可见时可能会被破坏。这可能会导致使用大量内存,因为片段实例可以保持任意数量的状态。
如您所见PageFragmentAdapter
,可以破坏每个我PageFragment
的,当然还有它的嵌套片段。并且当它将被重新创建时,它将具有 NULL 而不是mFragment
值。我正在尝试通过保存它getChildFragmentManager().putFragment()
,然后通过getChildFragmentManager().getFragment()
. 但它不起作用。
问题
所以我的问题是:如何将我的嵌套片段保存在我的父片段中?可能吗?
非常感谢您的帮助。亚历克斯。PS真的对不起我的英语:)
编辑
谢谢@AndroidBegin.com 的答案!
这似乎是新添加的对嵌套片段的支持中的一个错误。基本上,子 FragmentManager 在与活动分离时最终会出现内部状态损坏。为我修复它的短期解决方法是将以下内容添加到您调用 getChildFragmentManager() 的每个 Fragment 的 onDetach() 中:
@Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}