Difference between add(), replace(), and addToBackStack()

后端 未结 9 1580
终归单人心
终归单人心 2020-11-22 05:40

What is the main difference between calling these methods:

fragmentTransaction.addToBackStack(name);
fragmentTransaction.replace(containerViewId, fragment, t         


        
相关标签:
9条回答
  • 2020-11-22 06:07

    1) fragmentTransaction.addToBackStack(str);

    Description - Add this transaction to the back stack. This means that the transaction will be remembered after it is committed, and will reverse its operation when later popped off the stack.

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

    Description - Replace an existing fragment that was added to a container. This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.

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

    Description - Add a fragment to the activity state. This fragment may optionally also have its view (if Fragment.onCreateView returns non-null) into a container view of the activity.

    What does it mean to replace an already existing fragment, and adding a fragment to the activity state and adding an activity to the back stack ?

    There is a stack in which all the activities in the running state are kept. Fragments belong to the activity. So you can add them to embed them in a activity.

    You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. This is essentially useful when you have defined your fragment container at different layouts. You just need to replace with any other fragment in any layout.

    When you navigate to the current layout, you have the id of that container to replace it with the fragment you want.

    You can also go back to the previous fragment in the backStack with the popBackStack() method. For that you need to add that fragment in the stack using addToBackStack() and then commit() to reflect. This is in reverse order with the current on top.

    findFragmentByTag does this search for tag added by the add/replace method or the addToBackStack method ?

    If depends upon how you added the tag. It then just finds a fragment by its tag that you defined before either when inflated from XML or as supplied when added in a transaction.

    References: FragmentTransaction

    0 讨论(0)
  • 2020-11-22 06:10

    Example an activity have 2 fragments and we use FragmentManager to replace/add with addToBackstack each fragment to a layout in activity

    Use replace

    Go Fragment1

    Fragment1: onAttach
    Fragment1: onCreate
    Fragment1: onCreateView
    Fragment1: onActivityCreated
    Fragment1: onStart
    Fragment1: onResume
    

    Go Fragment2

    Fragment2: onAttach
    Fragment2: onCreate
    Fragment1: onPause
    Fragment1: onStop
    Fragment1: onDestroyView
    Fragment2: onCreateView
    Fragment2: onActivityCreated
    Fragment2: onStart
    Fragment2: onResume
    

    Pop Fragment2

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

    Pop Fragment1

    Fragment1: onPause
    Fragment1: onStop
    Fragment1: onDestroyView
    Fragment1: onDestroy
    Fragment1: onDetach
    

    Use add

    Go Fragment1

    Fragment1: onAttach
    Fragment1: onCreate
    Fragment1: onCreateView
    Fragment1: onActivityCreated
    Fragment1: onStart
    Fragment1: onResume
    

    Go Fragment2

    Fragment2: onAttach
    Fragment2: onCreate
    Fragment2: onCreateView
    Fragment2: onActivityCreated
    Fragment2: onStart
    Fragment2: onResume
    

    Pop Fragment2

    Fragment2: onPause
    Fragment2: onStop
    Fragment2: onDestroyView
    Fragment2: onDestroy
    Fragment2: onDetach
    

    Pop Fragment1

    Fragment1: onPause
    Fragment1: onStop
    Fragment1: onDestroyView
    Fragment1: onDestroy
    Fragment1: onDetach
    

    Sample project

    0 讨论(0)
  • 2020-11-22 06:16

    Although it is an old question already answered, maybe those next examples can complement the accepted answer and they can be useful for some new programmers in Android as I am.

    Option 1 - "addToBackStack()" is never used

    Case 1A - adding, removing, and clicking Back button

    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
    

    Case 1B - adding, replacing, and clicking Back button

    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()" is always used

    Case 2A - adding, removing, and clicking Back button

    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
    

    Case 2B - adding, replacing, removing, and clicking Back button

    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()" is not used always (in the below examples, w/o indicates that it is not used)

    Case 3A - adding, removing, and clicking Back button

    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
    

    Case 3B - adding, replacing, removing, and clicking Back button

    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
    
    0 讨论(0)
  • 2020-11-22 06:17

    When We Add First Fragment --> Second Fragment using add() method

     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();
    
                }
            });
    

    When we use add() in 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
    

    When we use replace() in fragment

    going to first fragment to second fragment in First -->Second using replace() method

     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 -------------------------- FirstFragment
    E/Keshav FirstFragment: onStop --------------------------- FirstFragment
    E/Keshav FirstFragment: onDestroyView -------------------- FirstFragment
    
    E/Keshav SecondFragment: onCreateView
    E/Keshav SecondFragment: onActivityCreated
    E/Keshav SecondFragment: onStart
    E/Keshav SecondFragment: onResume
    

    In case of Replace First Fragment these method is extra called ( onPause,onStop,onDestroyView is extra called )

    E/Keshav FirstFragment: onPause

    E/Keshav FirstFragment: onStop

    E/Keshav FirstFragment: onDestroyView

    0 讨论(0)
  • 2020-11-22 06:22

    One more important difference between add and replace is this:

    replace removes the existing fragment and adds a new fragment. This means when you press back button the fragment that got replaced will be created with its onCreateView being invoked. Whereas add retains the existing fragments and adds a new fragment that means existing fragment will be active and they wont be in 'paused' state hence when a back button is pressed onCreateView is not called for the existing fragment(the fragment which was there before new fragment was added).

    In terms of fragment's life cycle events onPause, onResume, onCreateView and other life cycle events will be invoked in case of replace but they wont be invoked in case of add.

    Edit: One should be careful if she is using some kind of event bus library like Greenrobot's Eventbus and reusing the same fragment to stack the fragment on top of other via add. In this scenario, even though you follow the best practice and register the event bus in onResume and unregister in onPause, event bus would still be active in each instance of the added fragment as add fragment wont call either of these fragment life cycle methods. As a result event bus listener in each active instance of the fragment would process the same event which may not be what you want.

    0 讨论(0)
  • 2020-11-22 06:22

    Basic difference between add() and replace() can be described as:

    • add() is used for simply adding a fragment to some root element.
    • replace() behaves similarly but at first it removes previous fragments and then adds next fragment.

    We can see the exact difference when we use addToBackStack() together with add() or replace().

    When we press back button after in case of add()... onCreateView is never called, but in case of replace(), when we press back button ... oncreateView is called every time.

    0 讨论(0)
提交回复
热议问题