FragmentTransaction.remove 没有效果
Posted
技术标签:
【中文标题】FragmentTransaction.remove 没有效果【英文标题】:FragmentTransaction.remove has no effect 【发布时间】:2012-10-30 15:43:09 【问题描述】:我的要求很简单:我有一个按钮应该用 FragmentB 替换 FragmentA。
这听起来很简单,几乎可以工作,最大的问题是旧片段没有被删除,新片段放在旧片段的前面,它们在我的布局中“生活”在一起。
守则:
FragmentManager fragMgr = a.getSupportFragmentManager();
Fragment currentFragment = (Fragment) fragMgr.findFragmentById(R.id.fragmentitself);
if(currentFragment!=null)
FragmentTransaction fragTrans = fragMgr.beginTransaction();
fragTrans.remove(currentFragment);
FragmentB newFragment = new FragmentB();
fragTrans.replace(R.id.fragmentcontainer, newFragment);
// I have also tried with R.id.fragmentitself
fragTrans.addToBackStack(null);
fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragTrans.commit();
布局:
<FrameLayout
android:layout_
android:layout_
android:layout_weight="2"
android:id="@+id/fragmentcontainer">
<fragment
android:id="@+id/fragmentitself"
android:name="com.WazaBe.MyApp.FragmentA"
android:layout_
android:layout_ />
</FrameLayout>
【问题讨论】:
【参考方案1】:解决方案
首先,您必须从 XML 中删除您的片段,并在其中保留空容器:
<FrameLayout
android:layout_
android:layout_
android:layout_weight="2"
android:id="@+id/fragmentcontainer" />
然后您需要从代码中添加您的 com.WazaBe.MyApp.FragmentA
片段,即在您的父 Activity 的 onCreate()
中。
说明
这是因为您的交易操纵了ViewGroup
的内容,例如FrameLayouts
。问题是,您只能操作从代码中添加的元素,因为从 XML 布局膨胀的任何内容都被视为“只读”。因此,当您将 Fragment 直接放入 XML 布局时,它会成为视图层次结构的 永久 一部分,并且因为它是永久的并且整个层次结构是“只读的”,所以它不能从代码中删除。
一旦您修复了布局并提取了 Fragment,就不再需要调用 remove()
- 只需执行 replace()
就足够了。
【讨论】:
@Marcin Orlowski 我在 FrameLayout 中有一个 ListView。如何从 onCreate 方法添加 ListView?我不能那样做。请帮助... 不确定你真正问的是什么,但我们在这里讨论片段,ListView 不是片段。如果您需要有关代码的任何帮助,您可能需要发布单独的问题。【参考方案2】:如果你想在一个视图容器中放置一个Fragment(比如一个Framelayout),你必须确保你的容器是空的(只有这样你才能在里面放一个Fragment)。你不能替换一个用XML写的Fragment文件,你应该通过JAVA代码将A添加到容器中,当你不需要id时,你可以将它替换为B;
首先,你的容器是空的:
<FrameLayout
android:layout_
android:layout_
android:layout_weight="2"
android:id="@+id/fragmentcontainer">
</FrameLayout>
好的,你把FragmentA放进去:
FragmentTransaction fragTrans = fragMgr.beginTransaction();
fragTrans.remove(currentFragment);
FragmentA fragA= new FragmentA();
fragTrans.add(R.id.fragmentcontainer, fragA).commit();
现在,如果你想替换:
FragmentTransaction fragTrans = fragMgr.beginTransaction();
FragmentB newFragment = new FragmentB();
fragTrans.replace(R.id.fragmentcontainer, newFragment);
// I have also tried with R.id.fragmentitself
fragTrans.addToBackStack(null);
fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragTrans.commit();
【讨论】:
【参考方案3】:如果我们在activity上使用Fragment容器,它需要选择一个默认的FragmentABC,即使我们使用ft.remove,默认的FragmentABC视图也无法移除。
如果您想在 Activity 启动时看到 Fragment 的空视图,请使用 FrameLayout 容器而不是 Fragment 容器。
【讨论】:
【参考方案4】:Kotlin 中的相同答案
private fun showDetailView(position: Int)
val fragTrans: FragmentTransaction = supportFragmentManager.beginTransaction()
val fragment: Fragment
when (position)
0 -> fragment = FragmentA()
1 -> fragment = FragmentB()
else ->
fragment = FragmentC()
fragTrans.replace(
R.id.itemDetailContainer,
fragment).commit()
fragTrans.addToBackStack(null);
fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
【讨论】:
以上是关于FragmentTransaction.remove 没有效果的主要内容,如果未能解决你的问题,请参考以下文章