我的问题
根据Google的文档:
现在您可以在碎片内嵌套碎片。这在想要将动态且可重复使用的UI组件放置到本身是动态且可重复使用的UI组件中的各种情况下非常有用。例如,如果您使用ViewPager创建可左右滑动且占用大部分屏幕空间的碎片,您现在可以将碎片插入到每个碎片页面中。 要嵌套碎片,只需在要添加碎片的Fragment上调用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
中的方法接收Fragment,并在我的PageFragment
中创建“嵌套Fragment”(当然是在onCreate()
中进行),例如:
getChildFragmentManager().beginTransaction()
.add(R.id.framelayout_history, mFragment)
.addToBackStack(null)
.commit();
注意:我使用PageFragment.setNestedFragment()
来设置其中的mFragment
。
它效果很好! 它将帮助我(但这个故事不是关于它的),简单地在ViewPager中替换片段,例如:
tPageFragmentAdapter.replaceFirstPage(tFragmentA);
但我有一个巨大的问题。再次谷歌文档:
PagerAdapter的实现,将每个页面表示为一个Fragment,并将其作为用户可以返回到该页面时在片段管理器中持久保存。当需要分页浏览一些通常比较静态的片段时,例如一组选项卡时,最好使用此版本的分页器。用户访问每个页面的片段将保留在内存中,尽管其视图层次结构可能在不可见时被销毁。这可能会导致使用大量内存,因为片段实例可以保持任意数量的状态。
如您所见,PageFragmentAdapter 可以销毁我的每个 PageFragment,当然也包括其中嵌套的片段。当它重新创建时,mFragment 值将为 NULL。我试图通过 getChildFragmentManager().putFragment() 来保存它,然后通过 getChildFragmentManager().getFragment() 来获取它。但是它没用。
问题
因此,我的问题是:如何在我的父片段中保存我的嵌套片段?这可能吗?
非常感谢您的帮助。Alex。P.S. 对于我的英语真的很抱歉:)
@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);
}
}