56 votes

Fragment déjà ajouté IllegalStateException

J'utilise cette méthode sur mon Activité conteneur pour afficher une BFrag

public void showBFrag()
{
    // Start a new FragmentTransaction
    FragmentTransaction fragmentTransaction = mFragmentMgr.beginTransaction();

    if(mBFrag.isAdded())
    {
        Log.d(LOG_TAG, "Show() BFrag");
        fragmentTransaction.show(mBFrag);   
    }
    else
    {
        Log.d(LOG_TAG, "Replacing AFrag -> BFrag");
        fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);
    }

    // Keep the transaction in the back stack so it will be reversed when backbutton is pressed
    fragmentTransaction.addToBackStack(null);

    // Commit transaction
    fragmentTransaction.commit();        
}

Je l'appelle de mes Activités de manutention de conteneurs; pour la première fois:

  • rentre dans le else et mBFrag remplacer mAFrag.

Alors j'ai appuyer sur le bouton de retour:

  • et le fonctionnement est inversé (mAFrag est montré, mais.. est-ce que mBFrag est supprimé?).

Puis-je aller de l'avant à nouveau en appelant showBFrag() de la même Activité:

  • et il obtient de NOUVEAU dans le else. (donc je peux en déduire que mBFrag n'est PAS AJOUTÉ)
  • mais j'ai reçu un Fragment déjà ajouté l'exception IllegalStateException... (alors pourquoi il n'a pas entrer dans l'instruction si à la place?)

Donc:

  1. Pourquoi le isAdded() la méthode ne retourne pas VRAI que si je reçois un Fragment déjà ajouté l'exception IllegalStateException??
  2. Ne popBackStack opération de supprimer complètement précédemment ajouté des fragments?
  3. Ce comportement je suis malentendu?

EDIT: Ici est l'info de l'exception.

06-07 12:08:32.730: ERROR/AndroidRuntime(8576): java.lang.IllegalStateException: Fragment already added: BFrag{40b28158 id=0x7f0c0085}
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.doAddOp(BackStackRecord.java:322)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.replace(BackStackRecord.java:360)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.replace(BackStackRecord.java:352)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at myPackageName.containerActivity.showBFrag() // This line: "fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);"

44voto

AMGG Points 1658

Enfin ma solution a été d'exécuter remove() du fragment précédent et ajouter() le nouveau. Même si c'est ce que méthode replace() est censé faire...

Mais j'ai encore de deviner pourquoi la méthode replace() n'a pas fonctionné dans ce cas... c'est vraiment bizarre et je veux jeter que c'est parce que je suis un malentendu quelque chose ou fait quelque chose de mal.

12voto

schwiz Points 13679

Si l'état de l'activité a déjà été enregistré son plus sûr d'appeler commettre. Vous devez appeler commitAllowingStateLoss() à la place. Espérons que cette aide!

Edit: ok j'ai pris un peu plus près à votre question, le problème est que vous tentez d'ajouter un fragment qui a déjà été ajouté. Même si vous utilisez de remplacer ou de retirer les appels que vous ne pouvez pas le faire. Seulement contourner que j'ai trouvé est de créer une nouvelle instance d'un fragment et de l'ajouter à chaque fois. Une fois que vous retirez ou remplacez un fragment, il est préférable de déposer l'ensemble de vos références afin que le GC peut prendre soin d'elle.

8voto

Johan Paul Points 424

Probablement pas lié à ce problème directement, mais j'ai également remarqué que définir une transition sur FragmentTransaction provoquera une exception IllegalStateException, alors que ne pas définir de transition ne le fera pas.

Voici le bogue pour ce problème: http://code.google.com/p/android/issues/detail?id=25598

0voto

ObviousChild Points 11

J'ai essayé d'appeler FragmentTransaction.remove() de onTabUnselected() et cela a fonctionné autour de ce bogue.

 @Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    ft.add(R.id.fragment_container, fragment, null);
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    ft.remove(fragment);
}
 

0voto

MuhammadAamirALi Points 2555

Ce code fonctionne bien pour moi. essaye ça

 ((MiActivity)getActivity()).addAccount = new AddAccount();
((MiActivity)getActivity()).addAccount.setArguments(params);
fragmentManager = getActivity().getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container((MiActivity)getActivity()).addAccount);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X