FragmentTransaction.удалить не имеет эффекта

мое требование довольно простое: у меня есть кнопка, которая должна заменить FragmentA на FragmentB.

это звучит легко и почти работает, большая проблема в том, что старый фрагмент не удаляется, а новый помещается на передней панели старого, и они "живут" вместе в моем макете.

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>

3 ответов


решение

во-первых, вы должны удалить свой фрагмент из 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-макете, то он становится постоянный часть иерархии представлений и поскольку она является постоянной, ее нельзя удалить из кода.

как только вы получите ваш макет исправлен,remove() вызов больше не нужен - достаточно будет просто сделать replace()


Если вы хотите поместить фрагмент в контейнер представления(например,Framelayout), вы должны убедиться, что ваш контейнер пуст (только это вы можете поместить в него фрагмент).вы не можете заменить фрагмент, записанный в XML-файле, вы должны добавить A в контейнер кодом JAVA, и когда вы не neet id, вы можете заменить его на B;

во-первых ,ваш контейнер empyt:

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

хорошо, вы положили фрагмент в него:

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

Если мы используем контейнер фрагментов в activity, требуется выбрать один фрагмент по умолчанию, представление по умолчанию FragmentABC не может быть удалено даже мы используем ft.удалять.

используйте контейнер FrameLayout вместо контейнера фрагмента, если вы хотите пустое представление фрагмента при запуске действия.