Fragment.isAdded возвращает true после удаления фрагмента из контейнера

У меня есть активность с макетом

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <FrameLayout android:id="@+id/frameLayoutA" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1" > </FrameLayout> <FrameLayout android:id="@+id/frameLayoutB" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1" > </FrameLayout> </LinearLayout> 

В onCreate of activity я загружаю Fragment_A в frameLayoutA и Fragment_B в frameLayoutB.

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); fmA=(FrameLayout) findViewById(R.id.frameLayoutA); fmB=(FrameLayout) findViewById(R.id.frameLayoutB); fragA=new FragmentA(); fragB=new FragmentB(); fragC=new FragmentC(); addFragmentsInActivity(R.id.frameLayoutA,fragA); addFragmentsInActivity(R.id.frameLayoutB,fragB); } public void addFragmentsInActivity(int id, Fragment fragment) { FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(id, fragment); fragmentTransaction.commit(); } 

Используя операцию меню, я хочу загрузить Fragment_B в frameLayoutA и Fragment_C в frameLayoutB. Операция меню:

  removeFragmentsInActivity(R.id.frameLayoutB,fragB); addFragmentsInActivity(R.id.frameLayoutB,fragC); if(!fragB.isAdded()){ Log.e("check", "fragB already removed from frameLayoutB"); removeFragmentsInActivity(R.id.frameLayoutB,fragB); addFragmentsInActivity(R.id.frameLayoutA,fragB); } else{ Log.e("check", "fragB already added"); } public void removeFragmentsInActivity(int id, Fragment fragment) { FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.remove(fragment); fragmentTransaction.commit(); } 

Fragment_B не отображается в frameLayoutA. FrameLayoutA показывает Fragment_A. При повторном нажатии кнопки меню загружается Fragment_B.

Отладка Я обнаружил, что после того, как fragB.isAdded () возвращает true после выполнения функции fragB.remove (). Во время операции 2-го меню выполняется функция fragB.isAdded () return false и fragB.add (), а FragmentB отображается в frameLayoutA.

Я понимаю, что commit – это асинхронная операция. IsAdded возвращает true, потому что commit isynyn и удаление операции commit не выполняется до момента вызова fragB.isAdded (). Это правда?

Просьба предложить возможное решение или подход для решения проблемы.

С уважением, Вихор

Solutions Collecting From Web of "Fragment.isAdded возвращает true после удаления фрагмента из контейнера"

Да, транзакция выполняется асинхронно. Если вы хотите убедиться, что все транзакции закончены, прежде чем выполнить isAdded , запустите:

 getFragmentManager().executePendingTransactions(); 

Из документации для executePendingTransactions() :

После того, как FragmentTransaction выполняется с помощью FragmentTransaction.commit (), он планируется выполнить асинхронно в основном потоке процесса. Если вы хотите немедленно выполнить любые такие ожидающие операции операции, вы можете вызвать эту функцию (только из основного потока), чтобы сделать это. Обратите внимание, что все обратные вызовы и другое связанное поведение будут выполняться из этого вызова, поэтому будьте осторожны, откуда это вызывается.

Поэтому ваш код должен выглядеть так:

 removeFragmentsInActivity(R.id.frameLayoutB,fragB); addFragmentsInActivity(R.id.frameLayoutB,fragC); getFragmentManager().executePendingTransactions(); if(!fragB.isAdded()){ Log.e("check", "fragB already removed from frameLayoutB"); removeFragmentsInActivity(R.id.frameLayoutA,fragA); addFragmentsInActivity(R.id.frameLayoutA,fragB); } else{ Log.e("check", "fragB already added"); } 

Отметим также фиксированное удаление фрагмента A.

Возможно, ваш может захватить процесс FragmentTransaction, как это

 private void commitFragmentTransaction(final FragmentTransaction ft, boolean allowStateLoss, boolean now) { if (ft == null || ft.isEmpty()) { return; } if (allowStateLoss) { if (now) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { ft.commitNowAllowingStateLoss(); } else { ft.commitAllowingStateLoss(); mFragmentManager.executePendingTransactions(); } } else { ft.commitAllowingStateLoss(); } } else { if (now) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { ft.commitNow(); } else { ft.commit(); mFragmentManager.executePendingTransactions(); } } else { ft.commit(); } } } 

CommitNow () и commitNowAllowingStateLoss () добавлено в уровень API 24

Вызов commitNow предпочтительнее вызова commit (), за которым следует executePendingTransactions (), поскольку последний будет иметь побочный эффект от попыток зафиксировать все текущие ожидающие транзакции, является ли это желаемым поведением или нет.