web-dev-qa-db-fra.com

Obtention d'une exception: fragment déjà actif

J'ai un fragment;

MyFragment myFrag = new MyFragment();

Je mets bundle data dans ce fragment:

Bundle bundle = new Bundle(); 
bundle.putString("TEST", "test");
myFrag.setArguments(bundle);

Ensuite, je remplacez l'ancien fragment par celui-ci et mettez sur le backstack:

//replace old fragment
fragmentTransaction.replace(R.id.fragment_placeholder, myFrag, "MyTag");
//put on backstack
fragmentTransaction.addToBackStack(null);
//commit & get transaction ID
int transId = fragmentTransaction.commit();

Plus tard, je pop backstack avec l'ID de transaction ci-dessus (transId):

//pop the transaction from backstack
fragmentManager.popBackStack(transId,FragmentManager.POP_BACK_STACK_INCLUSIVE); 

Plus tard, j'ai de nouveau bundle data comme argument pour mon fragment (myFrag):

//Got Java.lang.IllegalStateException: fragment already active
myFrag.setArguments(bundle);

Comme vous le voyez, mon code ci-dessus a obtenu une exception Java.lang.IllegalStateException: fragment already active. Je ne comprends pas pourquoimyFragest toujours actif même si j'en ai sauté la transaction depuis backstack., de toute façon, puisque j'ai eu l'exception que je pensais Je n'ai pas d'autre choix que de désactiver le fragment, alors j'ai fait:

Fragment activeFragment = fragMgr.findFragmentByTag("MyTag");
fragmentTransaction.remove(activeFragment);

Je ne sais pas si mon code ci-dessus peut vraiment désactiver le fragment, car je n'ai pas trouvé comment désactiver un fragment. :(

Après cela, lorsque j'essaie de définir à nouveau les données de l'ensemble sur mon fragment myFrag, j'ai toujours la même erreur:

Java.lang.IllegalStateException: fragment already active

On dirait même que j'ai supprimé le fragment, il est toujours actif ...Pourquoi? Comment désactiver un fragment?

57
Leem.fin

La lecture de la source setArguments (Bundle args) vous aidera à comprendre:

/**
* Supply the construction arguments for this fragment.  This can only
* be called before the fragment has been attached to its activity; that
* is, you should call it immediately after constructing the fragment.  The
* arguments supplied here will be retained across fragment destroy and
* creation.
*/
public void setArguments(Bundle args) {

    if (mIndex >= 0) {
        throw new IllegalStateException("Fragment already active");
    }
    mArguments = args;
}

Vous ne pouvez pas utiliser setArguments (Bundle args) à nouveau dans votre code sur le même Fragment . Ce que vous voulez faire, je suppose, c'est créer un nouveau Fragment et définissez à nouveau les arguments. Ou vous pouvez utiliser getArguments () puis utiliser la méthode put du bundle pour modifier ses valeurs.

149
Assaf Gamliel

Essayez de supprimer le fragment précédent avant d'ajouter le nouveau: https://stackoverflow.com/a/6266144/969325

1
Warpzit

remove () change le statut du fragment en de-actiive. Dans votre cas, vous n'avez tout simplement pas appelé commit () après avoir supprimé (..).

fragmentTransaction.remove(activeFragment);

Vous feriez aussi commit () après remove ().

fragmentTransaction.remove(activeFragment).commit();
1
Joshua

Appelez simplement la méthode publique à partir d'un fragment

if(userFragment==null){
                    userFragment = new UserFragment();
                    Bundle bundle = new Bundle();
                    bundle.putString(Constants.EXTRA_CUSTOMER, result);
                    userFragment.setArguments(bundle);
                }else{
                    try {
                        Customer customer = new Customer();
                        customer.parseCustomer(new JSONObject(result));
                        userFragment.updateVeiw(customer);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
0
Krzysztof Dziuba

Je commence par décrire pourquoi cela se produit, puis je proposerai la solution que j'ai trouvée efficace ....

Ce problème se produit lorsque Android est supprimant le fragment de la pile mais est pas encore terminé avec la suppression. Pour vérifier cela, vous pouvez utiliser la méthode isRemoving() du fragment. Si false, c'est-à-dire que le fragment n'est pas actif, vous pouvez continuer à définir les arguments en utilisant setArguments(bundle). Sinon, vous ne pouvez pas définir d'arguments sur un fragment déjà actif et ne pouvez le remplacer qu'en adressant les mêmes arguments à l'aide de getArguments().putAll(bundle).

Résumer,

    if (myFrag.isRemoving()) {
        myFrag.getArguments().putAll(bundle);
    } else {
        myFrag.setArguments(bundle);
    }

Si vous voulez éviter cela, c'est-à-dire supprimer le fragment à la fois afin qu'il n'y ait pas de fragment actif, vous pouvez utiliser onBackPressed() dans onBackStackChangedListener(), ce qui définira isRemoving() sur false.

0
Ali Nem

Je rencontre le même problème sur Xamarin.Android. Voici ce que la documentation dit.

Cela ne peut être appelé que lorsque le fragment a été attaché à son activité

0
Jonathan

Eu le même problème. J'ajoutais le fragment à backstack. Et l'erreur était parce que je n'ai pas appelé popbackstack (). L'utilisation de popbackstack m'a aidé

0