J’ai une activité hébergeant deux fragments. L’activité commence par montrer un chargeur pendant qu’il charge un object. L’object chargé est ensuite transmis aux deux fragments en tant qu’arguments via les méthodes newInstance et ces fragments sont attachés.
final FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); trans.replace(R.id.container1, Fragment1.newInstance(loadedObject)); trans.replace(R.id.container2, Fragment2.newInstance(loadedObject)); trans.commit();
Le second fragment contient un android.support.v4.view.ViewPager et des tabs. onResume on l’initialise comme suit
viewPager.setAdapter(adapter); viewPager.setOffscreenPageLimit(adapter.getCount()); //the count is always < 4 tabLayout.setupWithViewPager(viewPager);
Le problème est android puis jette
java.lang.IllegalStateException: FragmentManager exécute déjà des transactions
Avec cette trace de stack: (j’ai pris android.support
des noms de paquet juste pour la brièveté)
v4.app.FragmentManagerImpl.execSingleAction (FragmentManager.java:1620) à la page v4.app.BackStackRecord.commitNowAllowingStateLoss (BackStackRecord.java:637) à l’adresse v4.app.FragmentPagerAdapter.finishUpdate (FragmentPagerAdapter.java:143) à l’adresse v4.view.ViewPager. .populate (ViewPager.java:1235) à v4.view.ViewPager.populate (ViewPager.java:1083) à v4.view.ViewPager.setOffscreenPageLimit (ViewPager.java:847)
Les données s’affichent si setOffscreenPageLimit(...);
est retiré. Y a-t-il un autre moyen d’éviter ce problème?
Quand dans le cycle de vie la transaction de fragment est-elle terminée pour que je puisse attendre pour configurer mon pager?
Si vous ciblez le SDK 24 et supérieur, vous pouvez utiliser:
FragmentTransaction.commitNow()
au lieu de commit()
Si vous ciblez des versions plus anciennes, essayez d’appeler:
FragmentManager.executePendingTransactions()
après l’appel à commit()
Utilisez simplement childFragmentManger()
pour viewpager
dans un Fragment
mPagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager()); mPager.setAdapter(mPagerAdapter);
J’ai eu cette exception en remplaçant rapidement 2 fragments ET en utilisant executePendingTransactions (). Sans appeler cela, il n’y avait pas d’exception.
Quel était mon cas? J’ouvre un fragment A et dans son onResume () (sous une condition) je demande à l’activité de remplacer le fragment avec le fragment B. À ce moment, l’exception se produit.
Ma solution consistait à utiliser un Handler.post (exécutable) qui place la requête à la fin de la queue au lieu de l’exécuter immédiatement. De cette façon, nous nous assurons que la nouvelle transaction sera exécutée une fois les transactions précédentes terminées.
Donc, ma solution était aussi simple que:
Handler uiHandler = new Handler(); uiHandler.post(new Runnable() { @Override public void run() { openFragmentB(position); } });