web-dev-qa-db-fra.com

Android FragmentTransaction.addToBackStack confusion

J'étudiais Fragments et je ne me suis pas trompé sur la différenciation des appels FragmentTransaction.replace(id, fragment, tag) et FragmentTransaction.addToBackStack(tag). Disons que mon fragment actuel est FragmentA puis j'ai chargé FragmentB. Je le veux à l'avenir, quand je dois charger FragmentA, je n'ai pas besoin de le recharger. Il suffit de charger l'ancien dans son ancien état. J'ai utilisé le segment de code suivant:

public void loadFragment(Fragment fragmentB, String tag) {
    FragmentManager fm = getSupportFragmentManager();
    View fragmentContainer = findViewById(R.id.fragment_container);

    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(fragmentContainer.getId(), fragmentB, tag);

    ft.addToBackStack(tag);

    ft.commit();
}

Maintenant, je suis confus, où dois-je ajouter la balise de chaîne? Dans replace() ou dans addToBackStack() ou dans les deux appels? Pouvez-vous expliquer la différence entre ces deux emplacements de balise?

17
Khawar Raza

Pouvez-vous expliquer la différence entre ces deux emplacements de balise?

La documentation pour addToBackStack est assez claire:

Un nom facultatif pour cet état de pile arrière, ou null.

Alors que pour replace :

Nom de balise facultatif pour le fragment, pour récupérer ultérieurement le fragment avec FragmentManager.findFragmentByTag (String).

Ces deux paramètres sont donc indépendants, l'un identifie la pile arrière, tandis que l'autre identifie le fragment dans Activity's FragmentManager.

Votre code semble correct de ce point de vue, juste que je ne rechercherais pas la vue fragmentContainer par son id, seulement pour utiliser ensuite son id pour remplacer le fragment. Rendez-le plus simple:

public void loadFragment(Fragment fragmentB, String tag) {
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.fragment_container, fragmentB, tag);

    ft.addToBackStack(null);

    ft.commit();
}

Si vous n'avez pas besoin d'identifier cette pile arrière ultérieurement, passez null pour addToBackStack. Au moins, je le fais toujours.

6
gunar

Dans cet exemple, vous n'avez pas besoin d'ajouter de balises comme identification. Faites juste:

ft.replace(R.id.fragment_container,fragmentB);
ft.addToBackStack(null);
ft.commit();

La balise d'identification est couramment utilisée lorsque vous souhaitez ajouter un fragment sans interface utilisateur.

5
K Roobroeck

Le paramètre passé à addToBackStack() peut être utilisé pour récupérer l'intégralité de l'objet BackStackEntry, pas seulement un seul fragment. Afin de définir la balise fragment, envisagez d'utiliser des versions à 3 paramètres d'add (int, Fragment, String) et replace (int, Fragment, String)

Avant d'ajouter le fragment, vous pourrez vérifier si ce fragment est déjà dans le backstack en utilisant:

 getFragmentMangager().findFragmentByTag(SettingsFragment.TAG);

Cela retournera null si le Fragment n'est pas déjà ajouté.

1
Jawad Zeb

Passer null à addtoBackStack (null) signifie ajouter le fragment dans la pile de fragments mais pas ajouter de TAG qui pourrait être utilisé pour identifier le fragment particulier dans une pile avant de l'ajouter à nouveau.

    .addToBackStack(null);

Mais passer TAG à addToBackStack aide à identifier le fragment dans la pile de fragments par TAG. Comme

.addToBackStack(FragmentName.TAG);

Maintenant, nous pouvons vérifier le fragment avant de l'ajouter à la pile:

 getFragmentManager().findFragmentByTag(SettingsFragment.TAG);

Cela renverra null si le fragment n'est pas déjà ajouté.

1
Narender Gusain