9

我的要求很简单:我有一个按钮应该用 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_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

4 回答 4

16

解决方案

首先,您必须从 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。问题是,您只能操作从代码中添加的元素,因为从 XML 布局膨胀的任何内容都被视为“只读”。因此,当您将 Fragment 直接放入 XML 布局时,它将成为视图层次结构的永久部分,并且因为它是永久的并且整个层次结构是“只读的”,所以它不能从代码中删除。

一旦您修复了布局并提取了 Fragment,remove()就不再需要调用 - 只需执行replace().

于 2012-11-10T15:08:09.843 回答
7

如果你想在 View Container 中放置 Fragment(例如 Framelayout),你必须确保你的容器是空的(只有这样你才能把 Fragment 放进去)。你不能替换写在 XML 文件中的 Fragment,你应通过JAVA代码将A添加到容器中,当您不需要id时,可以将其替换为B;

首先,你的容器是空的:

<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();
于 2012-11-10T15:38:45.937 回答
0

如果我们在activity上使用Fragment容器,它需要选择一个默认的FragmentABC,即使我们使用ft.remove,默认的FragmentABC视图也无法移除。

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

于 2018-07-11T11:24:45.147 回答
0

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);
        }
    
    }
于 2020-08-06T11:52:39.507 回答