假设我有4个片段A B C和D.
A和B是主要碎片,C和D是次要的。
我使用导航抽屉切换片段。
A是默认的起始片段。
我想实现以下功能,但无法弄清楚如何使用片段管理器和事务。
实现此功能的唯一方法是我应该编写一些复杂的函数来切换片段(还需要保留当前片段和所需的目标片段)?
有更好的出路吗?
根据@DeeV的回答,我出现了类似的内容。
LocalBrowse和WebsiteExplore是主要片段,而“设置”和“关于”是子片段。
似乎工作正常,但仍然有点难看,还有更好的主意吗?
private void switchToFragment(Class<?> targetFragmentClz) {
if(mCurrentFagment!=null && mCurrentFagment.getClass().equals(targetFragmentClz)) {
return;
}
BaseFragment targetFragment = null;
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if(targetFragmentClz.equals(LocalBrowseFragment.class)
|| targetFragmentClz.equals(WebsiteExploreFragment.class)) {
if(mCurrentFagment instanceof SettingsFragment //mCurrentFragment will not be null this time
|| mCurrentFagment instanceof AboutFragment) {
transaction.remove(mCurrentFagment);
}
if(mCurrentMainFagment==null || !mCurrentMainFagment.getClass().equals(targetFragmentClz)) {
targetFragment = (BaseFragment) Fragment.instantiate(this, targetFragmentClz.getName());
targetFragment.setHasOptionsMenu(true);
transaction.replace(R.id.ac_content_frame_main, targetFragment);
mCurrentMainFagment = targetFragment;
}
} else {
targetFragment = (BaseFragment) Fragment.instantiate(this, targetFragmentClz.getName());
targetFragment.setHasOptionsMenu(true);
getSupportFragmentManager().popBackStackImmediate();
transaction.replace(R.id.ac_content_frame_sub, targetFragment)
.addToBackStack(null);
}
transaction.commit();
mCurrentFagment = targetFragment;
}
答案 0 :(得分:2)
我能想到的一种方法是将两种类型的片段堆叠在一起。所以像这样的系统:
<FrameLayout>
<FrameLayout id="main_container">
<FrameLayout id="sub_container">
<FrameLayout>
意味着您有两个容器存放碎片。顶部完全覆盖另一个。因此,你可以有两种方法:
public void swapMainContainer(FragmentManager fm, Fragment frag)
{
fm.beginTransaction().
.replace(R.id.main_container, frag, "TAG")
.commit();
}
public void swapSubContainer(FragmentManager fm, Fragment frag)
{
fm.popBackstackImmediate();
fm.beginTransaction()
.replace(R.id.sub_container, frag, "SUBTAG")
.addToBackStack(null)
.commit();
}
因此,如果仅将swapMainContainer()
与片段A和片段B一起使用,它们将不断相互替换,但提交将不会添加到后台堆栈中。
如果仅将swapSubContainer()
与片段C和片段D一起使用,它们将同样互相替换,但“后退”将关闭它们。每次提交子片段时都会弹出backstack,从而删除先前的提交。但是,如果靠背中没有任何东西,它就不会做任何事情。
要删除C / D,只需调用popBackStack()
,它就会将其从堆栈中删除。
然而,这种方法的缺陷是,如果你有两个以上的碎片被添加到后台堆叠中。它可能会被破坏。
编辑:
关于保存视图状态,片段本身必须通过this method.
处理