В чем разница между отсоединением фрагмента и его удалением?

118

В документации Android для FragmentTransaction я заметил два очень похожих метода: detachи remove. Описания там, кажется, не дают большого представления о том, когда использовать каждый, и, насколько я могу судить, они кажутся одинаковыми.

Итак: в чем разница между этими двумя методами?

yydl
источник

Ответы:

156

Метод отсоединения удаляет фрагмент из пользовательского интерфейса, но его состояние поддерживается диспетчером фрагментов. Это означает, что вы можете повторно использовать этот фрагмент, вызвав метод attach с измененной ViewHierarchy

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

Комментарий к источнику

Вы заметите, что при отсоединении фрагмента вызываются только его методы onPause, onStop и onDestroyView (в указанном порядке). С другой стороны, когда фрагмент удаляется, вызываются его методы onPause, onStop, onDestroyView, onDestroy и onDetach (в указанном порядке). Аналогично, при присоединении вызываются только методы фрагмента onCreateView, onStart и onResume; и при добавлении вызываются методы фрагмента onAttach, onCreate, onCreateView, onStart и onResume (в указанном порядке). - Адиль Хуссейн

Радждип Дуа
источник
145
Для того, чтобы добавить ответ Rajdeep, вы заметите , что , когда Fragmentэто отдельно стоящий , его onPause, onStopи onDestroyViewметоды называются только (в таком порядке). С другой стороны, когда Fragmentбудет удалена , ее onPause, onStop, onDestroyView, onDestroyи onDetachметоды называются (в указанном порядке). Аналогичным образом , когда прикрепления , то Fragment«ы onCreateView, onStartи onResumeметоды называются только; и когда добавление , что Fragment«ы onAttach, onCreate, onCreateView, onStartи onResumeметоды называются (в указанном порядке).
Адиль Хуссейн
1
Существует быстрый Q & А с Дианой Hackborn здесь . Так зачем мне этот журнал? Откуда вы знаете, что был вызван FT.detach ()?
Poutrathor
1
В чем преимущество одного перед другим? Я хочу знать вариант использования, когда одно предпочтительнее другого? Я всегда добавляю и удаляю, это плохо?
Neon Warge
1
Лучшее краткое и краткое разъяснение.
Robotec
55

Названия методов управления фрагментами очень сбивают с толку даже инженеры Google на досках сообщений (см. Комментарии выше). Я сделал себе небольшую демонстрацию, чтобы понять, как все работает на самом деле. Вот мои выводы. Не стесняйтесь поправлять меня, если я ошибаюсь.

Чтобы изначально добавить фрагмент в действие, вы используете: getFragmentManager (). BeginTransaction (). Add (R.id.container, mFragment) .commit ().

Это связывает действие с фрагментом, а также связывает представление с фрагментом.

Вот итоговые события жизненного цикла и другие важные возвращаемые значения метода:

onAttach()           
onCreate()           
onCreateView()       
onViewCreated()      
onActivityCreated()  
onViewStateRestored()
onStart()            
onResume()

mFragment.getView() == null: false                    
mFragment.getActivity() == null: false

Чтобы удалить фрагмент из действия, вы используете: getFragmentManager (). BeginTransaction (). Remove (mFragment) .commit ().

Это удаляет любую связь с представлением или действием.

Вот итоговые события жизненного цикла и другие важные возвращаемые значения метода:

onPause()
onStop()
onDestroyView()
onDestroy()
onDetach()

mFragment.getView() == null: true
mFragment.getActivity() == null: true

Я повторно добавил фрагмент сюда

Чтобы отделить добавленный фрагмент от действия, вы используете: getFragmentManager (). BeginTransaction (). Detach (mFragment) .commit ().

Это удаляет любую связь с представлением, но сохраняет связь с действием.

Вот итоговые события жизненного цикла и другие важные возвращаемые значения метода:

onPause()                             
onStop()                              
onDestroyView()                      

mFragment.getView() == null: true
mFragment.getActivity() == null: false

Чтобы повторно присоединить фрагмент, который был отсоединен от Activity, вы используете: getFragmentManager (). BeginTransaction (). Attach (mFragment) .commit ().

Это создает новое представление для связи с фрагментом и поддерживает связь действия.

Вот итоговые события жизненного цикла и другие важные возвращаемые значения метода:

onCreateView()                        
onViewCreated()                       
onActivityCreated()                   
onViewStateRestored()                 
onStart()                             
onResume()                            

mFragment.getView() == null: false
mFragment.getActivity() == null: false

Другие важные замечания: если вы отсоедините фрагмент, а затем попытаетесь добавить его снова, используя add (), а не attach (), ничего не изменится.

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

Когда getView () возвращает значение null, фрагмент все еще может иметь внутренние ссылки на последнее созданное представление. Это представление больше недействительно и не должно использоваться.

Стивен
источник
1
Хорошая работа. Но мне показалось довольно интересным, что попытки повторного присоединения и повторного добавления имеют тот же эффект после удаления фрагмента.
stdout
9
Оказалось, что «attach ()» не будет вызывать onAttach (). «detach ()» не будет вызывать onDetach ().
KunYu Tsai
1
И некоторые из этих событий жизненного цикла могут немного измениться, если вы сохраните транзакции в заднем стеке.
stdout