web-dev-qa-db-fra.com

Différence entre add (), replace () et addToBackStack ()

Quelle est la principale différence entre l'appel de ces méthodes:

fragmentTransaction.addToBackStack(name);
fragmentTransaction.replace(containerViewId, fragment, tag);
fragmentTransaction.add(containerViewId, fragment, tag);

Qu'est-ce que cela signifie de remplacer un fragment déjà existant et d'ajouter un fragment à l'état d'activité et d'ajouter une activité à la pile arrière?

Deuxièmement, avec findFragmentByTag(), cette recherche de balise est-elle ajoutée par la méthode add()/replace() ou la méthode addToBackStack()?

254
AndroidDev

1)fragmentTransaction.addToBackStack(str);

Description - Ajoutez cette transaction à la pile arrière. Cela signifie que la transaction sera mémorisée une fois qu'elle est validée et inversera son opération lorsqu'elle sera extraite ultérieurement de la pile.

2)fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)

Description - Remplace un fragment existant qui a été ajouté à un conteneur. Ceci est essentiellement identique à l'appel de remove (Fragment) pour tous les fragments actuellement ajoutés qui ont été ajoutés avec le même conteneurViewId, puis add (int, Fragment, String) avec les mêmes arguments que ceux donnés ici.

3)fragmentTransaction.add(int containerViewId, Fragment fragment, String tag)

Description - Ajoute un fragment à l'état d'activité. Ce fragment peut éventuellement aussi avoir sa vue (si Fragment.onCreateView renvoie non-null) dans une vue conteneur de l'activité.

Qu'est-ce que cela signifie de remplacer un fragment déjà existant et d'ajouter un fragment à l'état d'activité et ajout d'une activité à l'arrière pile?

Il existe une pile dans laquelle sont conservées toutes les activités en cours d'exécution. Les fragments appartiennent à l'activité. Vous pouvez donc les ajouter pour les intégrer à une activité.

Vous pouvez combiner plusieurs fragments en une seule activité pour créer une interface utilisateur à volets multiples et réutiliser un fragment dans plusieurs activités. Ceci est essentiellement utile lorsque vous avez défini votre conteneur de fragments selon différentes dispositions. Vous devez simplement remplacer par n'importe quel autre fragment dans n'importe quelle mise en page.

Lorsque vous accédez à la mise en page actuelle, vous disposez de l'id de ce conteneur pour le remplacer par le fragment souhaité. 

Vous pouvez également revenir au fragment précédent dans le backStack avec la méthode popBackStack(). Pour cela, vous devez ajouter ce fragment dans la pile en utilisant addToBackStack() puis commit() pour refléter. C'est dans l'ordre inverse avec le courant en haut.

findFragmentByTag effectue cette recherche pour la balise ajoutée par l’ajout/remplacement méthode ou la méthode addToBackStack?

Si dépend de la façon dont vous avez ajouté la balise. Il trouve ensuite simplement un fragment par sa balise que vous avez définie auparavant, soit lorsqu'elle est gonflée à partir de XML, soit telle qu'elle est fournie lors de l'ajout dans une transaction.

Références: FragmentTransaction

290
My God

Une autre différence d'importance entre add et replace est la suivante: replace supprime le fragment existant et ajoute un nouveau fragment. Cela signifie que lorsque vous appuierez sur le bouton Précédent, le fragment qui aura été remplacé sera créé et son onCreateView sera invoqué. Considérant que add conserve les fragments existants et ajoute un nouveau fragment, ce qui signifie que le fragment existant sera actif et qu’ils ne seront pas dans l’état "en pause". Par conséquent, lorsqu’un bouton Précédent est activé, Créée ne sera pas appelée pour le fragment existant (le fragment fragment a été ajouté). En termes d'événements de cycle de vie de fragment, onPause, onResume, onCreateView et d'autres événements de cycle de vie seront invoqués dans le cas de replace, mais ils ne le seront pas dans le cas de add

Edit: Soyez prudent si elle utilise une sorte de bibliothèque de bus d’événements telle que le bus de événements de Greenrobot et qu’elle réutilise le même fragment pour empiler celui-ci sur une autre via add. Dans ce scénario, même si vous suivez la meilleure pratique et enregistrez le bus d'événements dans onResume et que vous n'enregistrez pas dans onPause, le bus d'événements serait toujours actif dans chaque instance du fragment ajouté, car add fragment n'appellera aucune de ces méthodes de cycle de vie. En conséquence, l'écouteur de bus d'événement dans chaque instance active du fragment traiterait le même événement, ce qui pourrait ne pas être ce que vous souhaitiez. 

291
Jeevan

Exemple, une activité a 2 fragments et nous utilisons FragmentManager pour remplacer/ajouter par addToBackstack chaque fragment à une présentation en activité

Utiliser remplacer

Go Fragment1

Fragment1: onCreateView
Fragment1: onStart
Fragment1: onResume

Go Fragment2

Fragment1: onStop
Fragment1: onDestroyView
Fragment2: onCreateView
Fragment2: onStart
Fragment2: onResume

Fragment Pop2

Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
Fragment1: onCreateView
Fragment1: onStart
Fragment1: onResume

Fragment Pop1

Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy

Utilisez add

Go Fragment1

Fragment1: onCreateView
Fragment1: onStart
Fragment1: onResume

Go Fragment2

Fragment2: onCreateView
Fragment2: onStart
Fragment2: onResume

Fragment Pop2

Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy

Fragment Pop1

Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy

Exemple de projet

52
Linh

La différence fondamentale entre add() et replace() peut être décrite comme suit:

  • add() est utilisé pour ajouter simplement un fragment à un élément racine.
  • replace() se comporte de la même manière, mais au début, il supprime les fragments précédents, puis ajoute le fragment suivant.

Nous pouvons voir la différence exacte lorsque nous utilisons addToBackStack() avec add() ou replace().

Lorsque nous appuyons sur le bouton Précédent après en cas de add()... onCreateView n'est jamais appelé, mais en cas de replace(), lorsque nous appuyons sur le bouton Précédent ... oncreateView est appelé à chaque fois.

15
Avanindra_dubey

Bien que ce soit une vieille question déjà répondue, peut-être que les exemples suivants peuvent compléter la réponse acceptée et qu'ils peuvent être utiles à certains nouveaux programmeurs sous Android comme moi.

Option 1 - "addToBackStack ()" n'est jamais utilisé

Cas 1A - ajouter, supprimer et cliquer sur le bouton Précédent

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
add Fragment C :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment B is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               App is closed, nothing is visible

Cas 1B - ajouter, remplacer et cliquer sur le bouton Précédent

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
(replace Fragment C)    
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()
Fragment C :        onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               App is closed, nothing is visible

Option 2 - "addToBackStack ()" est toujours utilisé

Cas 2A - ajouter, supprimer et cliquer sur le bouton Précédent

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
add Fragment C :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView()                              Fragment B is visible
(Back button clicked)
Fragment C :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment C is visible
(Back button clicked)
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment B is visible
(Back button clicked)
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment A is visible
(Back button clicked)
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible

Cas 2B - ajouter, remplacer, supprimer et cliquer sur le bouton Précédent

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
(replace Fragment C)    
Fragment B :        onPause() - onStop() - onDestroyView()  
Fragment A :        onPause() - onStop() - onDestroyView() 
Fragment C :        onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView()                              Activity is visible
(Back button clicked)
Fragment C :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment C is visible
(Back button clicked)
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onCreateView() - onActivityCreated() - onStart() - onResume()   
Fragment B :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment B is visible
(Back button clicked)
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment A is visible
(Back button clicked)
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible

Option 3 - "addToBackStack ()" n'est pas toujours utilisé (dans les exemples ci-dessous, w/o indique qu'il n'est pas utilisé)

Cas 3A - ajouter, supprimer et cliquer sur le bouton Précédent

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B w/o:     onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
add Fragment C w/o:     onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment B is visible
(Back button clicked)
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible

Cas 3B - ajouter, remplacer, supprimer et cliquer sur le bouton Précédent

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B w/o:     onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
(replace Fragment C)    
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()   
Fragment A :        onPause() - onStop() - onDestroyView() 
Fragment C :        onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView()                              Activity is visible
(Back button clicked)
Fragment C :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment C is visible
(Back button clicked)
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment A is visible
(Back button clicked)
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible
3
Javi

Lorsque nous ajoutons un premier fragment -> Deuxième fragment en utilisant la méthode add ()

 btn_one.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity(),"Click First 
Fragment",Toast.LENGTH_LONG).show();

                Fragment fragment = new SecondFragment();
                getActivity().getSupportFragmentManager().beginTransaction()
                        .add(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();
//                        .replace(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();

            }
        });

Lorsque nous utilisons add () dans un fragment

E/Keshav SecondFragment: onAttach
E/Keshav SecondFragment: onCreate
E/Keshav SecondFragment: onCreateView
E/Keshav SecondFragment: onActivityCreated
E/Keshav SecondFragment: onStart
E/Keshav SecondFragment: onResume

Lorsque nous utilisons replace () dans un fragment

aller au premier fragment au deuxième fragment dans First -> Second en utilisant la méthode replace ()

 btn_one.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity(),"Click First Fragment",Toast.LENGTH_LONG).show();

                Fragment fragment = new SecondFragment();
                getActivity().getSupportFragmentManager().beginTransaction()
//                        .add(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();
                        .replace(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();

            }
        });

E/Keshav SecondFragment: onAttach
E/Keshav SecondFragment: onCreate

E/Keshav FirstFragment: onPause

E/Keshav FirstFragment: onStop

E/Keshav FirstFragment: onDestroyView

E/Keshav SecondFragment: onCreateView
E/Keshav SecondFragment: onActivityCreated
E/Keshav SecondFragment: onStart
E/Keshav SecondFragment: onResume
1
Keshav Gera

add () ... c'est utilisé pour ajouter un fragment à framelayout et utilisé pour cet inconvénient, c'est qu'un fragment précédent peut apparaître en arrière-plan

transaction.add(R.id.framelayout, fragment);

replace () ... ceci est utilisé pour remplacer un fragment à framelayout et utilisé pour cet avantage. Son fragment précédent ne peut pas apparaître en arrière-plan, mais stocke tous les fragments

transaction.replace(R.id.framelayout, fragment);

addToBackStack () ... est utilisé pour stocker tous les fragments en arrière-plan et lorsque l'utilisateur peut appuyer sur le bouton Précédent puis naviguer vers le fragment précédent

transaction.addToBackStack(null);
0
MD Khali