Est-ce la bonne façon de nettoyage Fragment arrière pile en sortant d'une pile profondément imbriqué?

StackOverflow https://stackoverflow.com/questions/5802141

Question

J'utilise la bibliothèque de compatibilité Android pour mettre en œuvre des fragments et ont étendu l'échantillon de mise en page de sorte qu'un fragment contient un bouton qui Déclenché un autre fragment.

Dans le volet de sélection à gauche j'ai 5 éléments sélectionnables -. A B C D E

Chaque charge jusqu'à un fragment (via FragmentTransaction:replace) dans le volet d'informations - a b c d e

Maintenant, j'ai étendu e fragment pour contenir un bouton qui charge un autre fragment e1 également dans le volet détails. Je l'ai fait sur la méthode de fragment e onClick comme suit:

FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details_frag, newFrag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();

Si je fais les sélections suivantes:

E - e - e1 - D - E

Alors fragment e est dans le volet détails. Cela est bien et ce que je veux. Cependant, si je frappe le bouton back à ce stade, il ne fait rien. Je dois cliquer deux fois parce que e1 est encore sur la pile. De plus après avoir cliqué sur autour je suis arrivé une exception de pointeur NULL dans onCreateView:

Pour « résoudre » ce problème, j'ajouté ce qui suit à chaque fois A B C D E est sélectionné:

FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
    fm.popBackStack();
}

Il suffit de se demander si cela est la bonne solution ou si je devrais faire quelque chose de différent?

Était-ce utile?

La solution

Eh bien il y a quelques façons d'aller à ce sujet en fonction du comportement prévu, mais ce lien devrait vous donner toutes les meilleures solutions et sans surprise est de Dianne Hackborn

http://groups.google.com/group/android-developers/browse_thread/thread / d2a5c203dad6ec42

Essentiellement, vous avez les options suivantes

  • Utilisez un nom pour votre état de pile arrière initiale et de l'utilisation FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE).
  • Utilisez FragmentManager.getBackStackEntryCount() / getBackStackEntryAt().getId() pour récupérer l'ID de la première entrée sur la pile de retour, et FragmentManager.popBackStack(int id, FragmentManager.POP_BACK_STACK_INCLUSIVE).
  • FragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) est censé sauter toute la pile arrière ... Je pense que la documentation qui est tout simplement faux. (En fait, je suppose que ça ne couvre pas le cas où vous passez POP_BACK_STACK_INCLUSIVE),

Autres conseils

L'autre solution propre si vous ne voulez pas sauter toutes les entrées pile ...

getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.home_activity_container, fragmentInstance).addToBackStack(null).commit();

Cela va nettoyer la pile d'abord, puis charger un nouveau fragment, donc à un moment donné, vous aurez seulement seul fragment dans la pile

Merci à Joachim réponse, j'utiliser le code pour effacer toutes les entrées de la pile de retour enfin.

// In your FragmentActivity use getSupprotFragmentManager() to get the FragmentManager.

// Clear all back stack.
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < backStackCount; i++) {

    // Get the back stack fragment id.
    int backStackId = getSupportFragmentManager().getBackStackEntryAt(i).getId();

    fm.popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);

} /* end of for */

J'ai étudié beaucoup pour le nettoyage Backstack, et enfin voir Transaction BackStack et son de gestion. Voici la solution qui fonctionne le mieux pour moi.

 // CLEAR BACK STACK.
    private void clearBackStack() {
        final FragmentManager fragmentManager = getSupportFragmentManager();
        while (fragmentManager.getBackStackEntryCount() != 0) {
            fragmentManager.popBackStackImmediate();
        }
    }

Les boucles de la méthode ci-dessus sur toutes les transactions dans le backstack et les supprime immédiatement un à la fois.

Remarque: code ci-dessus quelque temps le travail non et le visage i ANR à cause de ce code, alors s'il vous plaît ne pas essayer.

Mise à jour ci-dessous méthode supprimer tous les fregment de ce « nom » de backstack.

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack("name",FragmentManager.POP_BACK_STACK_INCLUSIVE);
    nom
  • Si non nul, c'est le nom d'un état de retour précédent chercher; si trouvé, tous les états jusqu'à cet état seront sauté. Le
  • drapeau POP_BACK_STACK_INCLUSIVE peut être utilisé pour contrôler si l'état du nom lui-même est sauté. Si nul, seul l'état supérieur est relevé.

J'utilise un code similaire à ceux qui utilisent la boucle while mais j'appeler le nombre d'entrées dans chaque boucle ... donc je suppose qu'il est un peu plus lent

FragmentManager manager = getFragmentManager();
while (manager.getBackStackEntryCount() > 0){
        manager.popBackStackImmediate();
    }
    // pop back stack all the way
    final FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
    int entryCount = fm.getBackStackEntryCount(); 
    while (entryCount-- > 0) {
        fm.popBackStack();
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top