Jaka jest różnica między odłączeniem fragmentu a jego usunięciem?

118

W dokumentacji Androida dla FragmentTransaction zauważyłem dwie bardzo podobne metody: detachi remove. Opisy tam nie wydają się dostarczać zbyt wielu informacji na temat tego, kiedy używać każdego z nich, az tego, co mogę powiedzieć, wydają się być takie same.

A więc: jakie są różnice między tymi dwiema metodami?

yydl
źródło

Odpowiedzi:

156

Metoda detach usuwa fragment z interfejsu użytkownika, ale jego stan jest utrzymywany przez menedżera fragmentów. Oznacza to, że możesz ponownie użyć tego fragmentu, wywołując metodę attach ze zmodyfikowaną ViewHierarchy

Usuń oznacza, że ​​instancji fragmentu nie można ponownie dołączyć. Będziesz musiał dodać go ponownie do transakcji fragmentarycznej.

Komentarz źródłowy

Zauważysz, że po odłączeniu fragmentu jego metody onPause, onStop i onDestroyView są wywoływane tylko (w tej kolejności). Z drugiej strony, gdy Fragment jest usuwany, wywoływane są jego metody onPause, onStop, onDestroyView, onDestroy i onDetach (w tej kolejności). Podobnie podczas dołączania metody onCreateView, onStart i onResume fragmentu są wywoływane tylko; a podczas dodawania są wywoływane metody onAttach, onCreate, onCreateView, onStart i onResume fragmentu (w tej kolejności). - Adil Hussain

Rajdeep Dua
źródło
145
Aby dodać odpowiedź Rajdeep użytkownika, można zauważyć, że gdy Fragmentjest wolnostojący , jego onPause, onStopi onDestroyViewmetody są wywoływane tylko (w tej kolejności). Z drugiej strony, gdy Fragmentzostanie usunięty , jego onPause, onStop, onDestroyView, onDestroyi onDetachmetody nazywane są (w tej kolejności). Podobnie, podczas mocowania , to Fragment„s onCreateView, onStarti onResumemetody nazywane są tylko; a gdy dodanie , że Fragment„a onAttach, onCreate, onCreateView, onStarti onResumemetody nazywane są (w tej kolejności).
Adil Hussain
1
Jest szybki Q & A z Diane Hackborn tutaj . Więc dlaczego mam ten dziennik? Skąd wiesz, że została wywołana funkcja FT.detach ()?
Poutrathor
1
Jaka jest przewaga jednego nad drugim? Chcę poznać przypadek użycia, w którym jeden jest korzystniejszy od drugiego? Zawsze dodam i usuwam, czy to źle?
Neon Warge,
1
Najlepsze krótkie i zwięzłe wyjaśnienie.
Robotec
55

Nazewnictwo metod zarządzania fragmentami jest bardzo mylące, nawet według inżynierów Google na forach dyskusyjnych (patrz komentarze powyżej). Zrobiłem sobie małe demo, aby dowiedzieć się, jak to naprawdę działa. Oto moje ustalenia. Jeśli się mylę, możesz mnie poprawić.

Aby początkowo dodać fragment do działania, użyj: getFragmentManager (). BeginTransaction (). Add (R.id.container, mFragment) .commit ().

To kojarzy działanie z fragmentem, a także kojarzy widok z fragmentem.

Oto wynikowe zdarzenia cyklu życia i inne ważne wartości zwracane przez metody:

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

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

Aby usunąć fragment z działania, użyj: getFragmentManager (). BeginTransaction (). Remove (mFragment) .commit ().

Spowoduje to usunięcie wszelkich skojarzeń z widokiem lub działaniem.

Oto wynikowe zdarzenia cyklu życia i inne ważne wartości zwracane przez metody:

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

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

Tutaj ponownie dodałem fragment

Aby odłączyć dodany fragment od działania, użyj: getFragmentManager (). BeginTransaction (). Detach (mFragment) .commit ().

Spowoduje to usunięcie wszelkich skojarzeń z widokiem, ale zachowa skojarzenie z działaniem.

Oto wynikowe zdarzenia cyklu życia i inne ważne wartości zwracane przez metody:

onPause()                             
onStop()                              
onDestroyView()                      

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

Aby ponownie dołączyć fragment, który został odłączony do działania, użyj: getFragmentManager (). BeginTransaction (). Attach (mFragment) .commit ().

Spowoduje to utworzenie nowego widoku do skojarzenia z fragmentem i zachowanie powiązania działania.

Oto wynikowe zdarzenia cyklu życia i inne ważne wartości zwracane przez metody:

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

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

Inne ważne rzeczy do zapamiętania: Jeśli odłączysz fragment, a następnie spróbujesz dodać go ponownie za pomocą add () zamiast attach (), nic nie wydaje się zmieniać.

Jeśli spróbujesz dodać fragment, który został usunięty za pomocą metody remove () przy użyciu attach () zamiast add (), nic się nie zmienia.

Gdy getView () zwraca wartość null, fragment może nadal mieć wewnętrzne odwołania do ostatniego utworzonego widoku. Ten widok nie jest już ważny i nie powinien być używany.

Stephen
źródło
1
Dobra robota. Ale wydawało się całkiem interesujące, że próba ponownego dołączenia i ponownego dodania daje ten sam efekt po usunięciu fragmentu.
stdout
9
Okazało się więc, że "attach ()" nie wywoła onAttach (). "detach ()" nie wywoła onDetach ().
KunYu Tsai
1
Niektóre z tych zdarzeń cyklu życia mogą się nieznacznie zmienić, jeśli będziesz przechowywać transakcje na zapleczu.
stdout