Разница между add(), replace() и addToBackStack()

В чем основное отличие между вызовами этих методов:

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

Что означает замена уже существующего фрагмента и добавление фрагмента в состояние активности и добавление активности в задний стек?

Во-вторых, с findFragmentByTag(), выполняет ли этот поиск тег, добавленный методом add()/replace(), или методом addToBackStack()?

Ответ 1

1) fragmentTransaction.addToBackStack(str);

Описание. Добавьте эту транзакцию в задний стек. Это означает, что транзакция будет запомнена после ее фиксации и изменит ее действие, когда позже выскочит из стека.

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

Описание. Замените существующий фрагмент, добавленный в контейнер. Это по сути то же самое, что и вызов remove (Fragment) для всех добавленных в настоящее время фрагментов, которые были добавлены с помощью одного и того же контейнера, а затем добавьте (int, Fragment, String) те же аргументы, которые приведены здесь.

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

Описание. Добавить фрагмент в состояние активности. Этот фрагмент может также иметь свой вид (если Fragment.onCreateView возвращает ненулевой) в представление контейнера активности.

Что означает замена уже существующего фрагмента и добавление фрагмент состояния активности и добавление активности к спине стек?

Существует стек, в котором хранятся все действия в рабочем состоянии. Фрагменты относятся к этой деятельности. Поэтому вы можете добавить их, чтобы внедрить их в действие.

Вы можете объединить несколько фрагментов в одном действии для создания многоуровневого пользовательского интерфейса и повторного использования фрагмента в нескольких действиях. Это существенно полезно, если вы определили контейнер фрагмента в разных макетах. Вам просто нужно заменить любым другим фрагментом в любом макете.

Когда вы переходите к текущему макету, у вас есть идентификатор этого контейнера, чтобы заменить его нужным фрагментом.

Вы также можете вернуться к предыдущему фрагменту в backStack с помощью метода popBackStack(). Для этого вам нужно добавить этот фрагмент в стек, используя addToBackStack(), а затем commit(), чтобы отразить. Это в обратном порядке с током сверху.

findFragmentByTag выполняет поиск по тегам, добавленным добавлением/заменой метод или метод addToBackStack?

Если это зависит от того, как вы добавили тег. Затем он просто находит фрагмент своим тегом, который вы определили до того, как он был взят из XML или предоставлен при добавлении в транзакцию.

Ссылки: FragmentTransaction

Ответ 2

Еще одно важное различие между add и replace: replace удаляет существующий фрагмент и добавляет новый фрагмент. Это означает, что при нажатии кнопки назад фрагмент, который был заменен, будет создан с вызовом onCreateView. Принимая во внимание, что add сохраняет существующие фрагменты и добавляет новый фрагмент, это означает, что существующий фрагмент будет активным, и они не будут находиться в состоянии "приостановлено", следовательно, при нажатии кнопки "Назад" onCreateView не вызывается для существующего фрагмента (фрагмент, который был там перед добавлением нового фрагмента). В терминах событий жизненного цикла фрагмента onPause, onResume, onCreateView и другие события жизненного цикла будут вызываться в случае replace, но они не будут вызываться в случае add.

Редактировать: нужно быть осторожным, если она использует какую-то библиотеку шины событий, такую как Greenrobot Eventbus, и повторно использует этот же фрагмент для укладки фрагмента поверх другого через add. В этом сценарии, даже если вы следуете передовой практике и регистрируете шину событий в onResume и отменяете регистрацию в onPause, шина событий все равно будет активна в каждом экземпляре добавленного фрагмента, поскольку фрагмент add не будет вызывать ни один из этих методы жизненного цикла фрагмента. В результате прослушиватель шины событий в каждом активном экземпляре фрагмента будет обрабатывать одно и то же событие, которое может не соответствовать вашему желанию.

Ответ 3

Пример действия имеет 2 фрагмента, и мы используем FragmentManager для замены/добавления на addToBackstack каждого фрагмента в макет в действии

Используйте заменить

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

Используйте добавить

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

Пример проекта

Ответ 4

Основное различие между add() и replace() можно описать так:

  • add() используется для простого добавления фрагмента в некоторый корневой элемент.
  • replace() ведет себя аналогично, но сначала удаляет предыдущие фрагменты, а затем добавляет следующий фрагмент.

Мы можем увидеть точную разницу, когда мы используем addToBackStack() вместе с add() или replace().

Когда мы нажимаем кнопку "назад" после, в случае add()... onCreateView никогда не вызывается, но в случае replace(), когда мы нажимаем кнопку назад... oncreateView вызывается каждый раз.

Ответ 5

Хотя это старый вопрос, на который уже дан ответ, возможно, эти следующие примеры могут дополнить принятый ответ, и они могут быть полезны для некоторых новых программистов в Android, как и я.

Вариант 1 - "addToBackStack()" никогда не используется

Случай 1А - добавление, удаление и нажатие кнопки "Назад"

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

Случай 1B - добавление, замена и нажатие кнопки "Назад"

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

Вариант 2 - "addToBackStack()" всегда используется

Случай 2А - добавление, удаление и нажатие кнопки "Назад"

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

Случай 2B - добавление, замена, удаление и нажатие кнопки "Назад"

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

Вариант 3 - "addToBackStack()" используется не всегда (в приведенных ниже примерах без указания указывает, что он не используется)

Случай 3А - добавление, удаление и нажатие кнопки "Назад"

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

Случай 3B - добавление, замена, удаление и нажатие кнопки "Назад"

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

Ответ 6

Когда мы добавляем первый фрагмент → второй фрагмент, используя метод 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();

            }
        });

Когда мы используем add() во фрагменте

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

Когда мы используем replace() во фрагменте

переход от первого фрагмента ко второму фрагменту в First → Second с использованием метода 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 -------------------------- 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

В случае замены первого фрагмента этот метод вызывается дополнительно (onPause, onStop, onDestroyView вызывается дополнительно)

E/Keshav FirstFragment: onPause

E/Keshav FirstFragment: onStop

E/Keshav FirstFragment: onDestroyView

Ответ 7

Функцию добавления и замены FragmentManger можно описать так: 1. add означает, что он добавит фрагмент в задний стек фрагментов и покажет в заданном вами кадре как

getFragmentManager.beginTransaction.add(R.id.contentframe,Fragment1.newInstance(),null)

2.replace означает, что вы заменяете фрагмент другим фрагментом в данном кадре

getFragmentManager.beginTransaction.replace(R.id.contentframe,Fragment1.newInstance(),null)

Основная утилита между ними заключается в том, что когда вы вернетесь в стек, замена обновит фрагмент, но добавление не обновит предыдущий фрагмент.

Ответ 8

add()... это использование для добавления фрагмента в framelayout и использование для этого disAdvantage - предыдущий фрагмент может отображаться в фоновом режиме

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

replace()... это использование для замены фрагмента в framelayout и использование этого преимущества: предыдущий фрагмент не может отображаться в фоновом режиме, но сохраняет весь фрагмент

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

addToBackStack()... используется для хранения всего фрагмента в фоновом режиме, и когда пользователь может нажать кнопку назад, затем перейти к предыдущему фрагменту

transaction.addToBackStack(null);