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

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

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

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

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

5 ответов

Решение

1) fragmentTransaction.addToBackStack(str);

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

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

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

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

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

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

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

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

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

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

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

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

Ссылки: FragmentTransaction

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

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

Вот изображение, которое показывает разницу между add() а также replace()

Так add()продолжает добавлять фрагменты поверх предыдущего фрагмента в FragmentContainer.

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

Что такое addToBackStack

addtoBackStackможно использовать с методами add() и replace. В Fragment API он служит другой цели.

Какая цель?

Fragment API, в отличие от Activity API, по умолчанию не имеет навигации по кнопке "Назад ". Если вы хотите вернуться к предыдущему фрагменту, тогда мы используем метод addToBackStack() во фрагменте. Давайте разберемся как

Случай 1:

getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragmentContainer, fragment, "TAG")
            .addToBackStack("TAG")
            .commit();

Случай 2:

getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragmentContainer, fragment, "TAG")
            .commit();

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

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

Go Fragment1

Fragment1: onCreateView
Fragment1: onStart
Fragment1: onResume

Go Fragment2

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

Pop Fragment2

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

Pop Fragment1

Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy

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

Go Fragment1

Fragment1: onCreateView
Fragment1: onStart
Fragment1: onResume

Go Fragment2

Fragment2: onCreateView
Fragment2: onStart
Fragment2: onResume

Pop Fragment2

Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy

Pop Fragment1

Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy

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

Хотя это старый вопрос, на который уже дан ответ, возможно, эти следующие примеры могут дополнить принятый ответ, и они могут быть полезны для некоторых новых программистов в 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

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

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

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

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

Важное замечание:

Разница между Replace и Replace with backstack заключается в том, что всякий раз, когда мы используем только replace, фрагмент уничтожается (вызывается ondestroy ()), а когда мы используем replace with backstack, тогда фрагменты onDestroy() не вызываются (то есть при нажатии кнопки возврата вызывается фрагмент с его onCreateView())

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

E / Keshav FirstFragment: onStop

E / Keshav FirstFragment: onDestroyView

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

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

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

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

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

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

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

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

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

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

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

transaction.addToBackStack(null);
Другие вопросы по тегам