Разница между 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);