FragmentTransaction.remove无效

时间:2012-11-10 14:45:00

标签: android fragment overlap

我的要求非常简单:我有一个按钮,应该用FragmentB替换FragmentA。

这听起来很容易并且几乎可以工作,最大的问题是旧的碎片没有被删除,新的碎片放在旧的碎片的前面,它们在我的布局中“生活”在一起。

enter image description here

守则:

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_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="2" 
    android:id="@+id/fragmentcontainer">

    <fragment
        android:id="@+id/fragmentitself"
        android:name="com.WazaBe.MyApp.FragmentA"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

4 个答案:

答案 0 :(得分:15)

<强>解决方案

首先,您必须从XML中删除您的片段,并在那里保留空容器:

<FrameLayout
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="2" 
    android:id="@+id/fragmentcontainer" />

然后,您需要在代码中添加com.WazaBe.MyApp.FragmentA片段,即在父级活动的onCreate()中。

<强>解释

这是因为您的交易操纵ViewGroup的内容,例如所述FrameLayouts。问题是,您只能操作从代码中添加的元素。因此,当您将Fragment直接放入XML布局时,它将成为View层次结构的永久部分,因为它是永久性的,所以无法从代码中删除它。

一旦修复了布局并提取了片段,就不再需要remove()调用了 - 只需执行replace()即可。

答案 1 :(得分:6)

如果要将片段放置在视图容器(例如Framelayout)中,则必须确保容器为空(只有这样才能将片段放入其中)。您无法替换XML中写入的片段文件,你应该通过JAVA代码将A添加到容器中,当你没有neet id时,你可以用B替换它;

首先,您的容器是empyt:

<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
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();

答案 2 :(得分:0)

如果我们在活动中使用Fragment容器,则需要选择一个默认的FragmentABC,即使使用ft.remove,也无法删除默认的FragmentABC视图。

如果要在活动启动时查看片段的空视图,请使用FrameLayout容器而不是Fragment容器。

答案 3 :(得分:0)

科特林的答案

   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);
        }
    
    }