web-dev-qa-db-fra.com

Comment supprimer un fragment spécifique de la pile arrière dans Android

J'ai un problème avec la suppression d'un fragment spécifique de la pile arrière. Mon scénario est le suivant: le fragment 1 est remplacé par le fragment 2, puis le fragment 2 est remplacé par le fragment 3.

Ordre d'appel; Fragment-1 -> Fragment-2 -> Fragment-3.

Lorsque le fragment 3 est à l'écran et que le bouton Précédent est cliqué, je veux y aller. 

Fragment-1.Cela signifie que je veux supprimer le Fragment-2 de la pile arrière.

Comment faire ça? 

17
nihasmata

Dans le backstack, vous n'avez pas Fragments, mais FragmentTransactions. Lorsque vous popBackStack(), la transaction est appliquée à nouveau, mais en arrière. Cela signifie que (en supposant que vous addToBackStackTrace(null) à chaque fois) dans votre backstack, vous avez

1->2
2->3

Si vous n’ajoutez pas la deuxième transaction au backstack, le résultat est que votre backstack est juste

1->2

en appuyant sur le bouton Précédent, l'exécution de 2->1 entraîne une erreur, car le fragment 2 n'est pas là (vous êtes sur le fragment 3).
La solution la plus simple est de faire sauter le backstack avant de passer de 2 à 3

//from fragment-2:
getFragmentManager().popBackStack();
getFragmentManager().beginTransaction()
   .replace(R.id.container, fragment3)
   .addToBackStack(null)
   .commit();

Ce que je fais ici est la suivante: du fragment 2, je reviens au fragment 1, puis directement au fragment 3. Ainsi, le bouton de retour me ramène de 3 à 1.

26
Ilario

J'ai eu un scénario très similaire au vôtre, ma solution consistait simplement à vérifier le nombre de transactions BackStack que j'avais.

Si les transactions étaient supérieures à 0, je les afficherais tout de suite donc il le sauterait en appuyant en arrière.

if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
        getSupportFragmentManager().popBackStackImmediate();
}
...
fragmentTransaction.replace(R.id.main_fragment, newFrag, MAIN_FRAGMENT_TAG);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();

Cela réussirait:

  • A -> B (dos appuyé) -> retour à A

  • A -> B -> C (dos appuyé) -> retour à A

Le seul inconvénient que je vois, c’est qu’il ya un éclair rapide où le fragment A est affiché avant de passer au fragment C.

9
Iv4n

Si vous ajoutez/lancez les trois fragments dans la même activité, au lieu de la méthode add() de FragmentTransaction pour afficher Fragment3, utilisez la méthode replace() de FragmentTransaction (remplacez Fragment2 par Fragment3). La méthode replace supprime le fragment actuel de backstack avant d'ajouter le nouveau fragment. Si vous lancez Fragment3 à partir d'une activité différente et que, par conséquent, vous ne pouvez pas/ne souhaitez pas utiliser replace(), supprimez Fragment2 du backstack avant de démarrer la nouvelle activité (qui ajoute fragment3):

// in Fragment2, before adding Fragment3:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
               .remove(this) // "this" refers to current instance of Fragment2
               .commit();
fragmentManager.popBackStack();
// now go ahead and launch (add) fragment3
// if fragment3 is launched from a different activity, 
// start that activity instead
fragmentManager.beginTransaction()
               .add(R.id.a_container_view_in_activity, new Fragment3(),
                    Fargment3.FRAGMENT3_ID)
               .commit();
4
Javad Sadeqzadeh

Code pour fragment A _ -> fragment B:

Ajouter Fragment A dans BackStack of Fragments

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout_container, new fragmentB());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

Code pour fragment B _ -> fragment C:

Ne pas ajouter Fragment B dans BackStack of Fragments

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout_container, new fragmentC());
fragmentTransaction.commit();

Cela fonctionnera de la manière suivante: A -> B -> C et tandis que revenant _ {C-> A comme vous l'avez excepté.

J'espère que cela vous aidera.

2
Hiren Patel

Vous ajoutez à l'état arrière à partir de la variable FragmentTransaction et supprimez-la à l'aide des méthodes FragmentManager pop:

FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove(myFrag);
trans.commit();
manager.popBackStack();

OU

Vous pouvez simplement ignorer le fragment ajouté dans la pile de fragments afin que lorsque vous revenez de Fragment-3, il revienne à Fragment-1

Mis à jour :

Pour désactiver l'animation, vous devez remplacer la méthode onCreateAnimation ...

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    if (disableAnim) {
        Animation a = new Animation() {};
        a.setDuration(0);
        return a;
    }
    return super.onCreateAnimation(transit, enter, nextAnim);
}
2
Kartheek
   for (int i = 0; i < mFragmentManager.getBackStackEntryCount(); i++) {
        currentFragment = mFragmentManager.getFragments().get(i);
        if (!(currentFragment instanceof ParticularFragment))
            mFragmentManager.popBackStack();
        else
            break;
    }
1
Rudee