Was ist der Unterschied zwischen dem Entfernen und Entfernen eines Fragments?

118

In den Android-Dokumenten für eine FragmentTransaction sind mir zwei sehr ähnliche Methoden aufgefallen: detachundremove . Die Beschreibungen dort scheinen nicht viel Aufschluss darüber zu geben, wann sie verwendet werden sollen, und soweit ich das beurteilen kann, scheinen sie gleich zu sein.

Also: Was sind die Unterschiede zwischen diesen beiden Methoden?

yydl
quelle

Antworten:

156

Die Methode "Entfernen" entfernt das Fragment von der Benutzeroberfläche, sein Status wird jedoch vom Fragment-Manager beibehalten. Dies bedeutet, dass Sie dieses Fragment wiederverwenden können, indem Sie die Methode attach mit einer geänderten ViewHierarchy aufrufen

Entfernen bedeutet, dass die Fragmentinstanz nicht erneut angehängt werden kann. Sie müssen es erneut zur Fragmenttransaktion hinzufügen.

Quellenkommentar

Sie werden feststellen, dass beim Trennen eines Fragments nur die Methoden onPause, onStop und onDestroyView aufgerufen werden (in dieser Reihenfolge). Wenn ein Fragment entfernt wird, werden die Methoden onPause, onStop, onDestroyView, onDestroy und onDetach (in dieser Reihenfolge) aufgerufen. In ähnlicher Weise werden beim Anhängen nur die Methoden onCreateView, onStart und onResume des Fragments aufgerufen. Beim Hinzufügen werden die Methoden onAttach, onCreate, onCreateView, onStart und onResume des Fragments aufgerufen (in dieser Reihenfolge). - Adil Hussain

Rajdeep Dua
quelle
145
Hinzufügen zu Rajdeep Antwort, werden Sie feststellen , dass , wenn eine Fragmentist freistehend , seine onPause, onStopund onDestroyViewMethoden nur genannt werden (in dieser Reihenfolge). Auf der anderen Seite, wenn ein Fragmentsich entfernt , sein onPause, onStop, onDestroyView, onDestroyund onDetachMethoden aufgerufen werden (in dieser Reihenfolge). Wenn in ähnlicher Weise angebracht , die Fragment‚s onCreateView, onStartund onResumeMethoden nur aufgerufen werden; und wenn das Hinzufügen , die Fragment‚s onAttach, onCreate, onCreateView, onStartund onResumeMethoden aufgerufen (in dieser Reihenfolge).
Adil Hussain
1
Es ist ein schneller Q & A mit Diane Hackborn hier . Warum habe ich dieses Protokoll? Woher wissen Sie, dass FT.detach () aufgerufen wurde?
Poutrathor
1
Was ist der Vorteil von einem gegenüber dem anderen? Ich möchte einen Anwendungsfall kennen, bei dem einer gegenüber dem anderen günstig ist. Ich füge immer hinzu und entferne, ist das schlecht?
Neon Warge
1
Beste kurze und prägnante Klarstellung.
Robotec
55

Die Benennung der Fragmentverwaltungsmethoden ist selbst laut Google-Ingenieuren in Message Boards sehr verwirrend (siehe Kommentare oben). Ich habe mir eine kleine Demo gemacht, um herauszufinden, wie die Dinge tatsächlich funktionieren. Hier sind meine Ergebnisse. Fühlen Sie sich frei, mich zu korrigieren, wenn ich falsch liege.

Um einer Aktivität zunächst ein Fragment hinzuzufügen, verwenden Sie: getFragmentManager (). BeginTransaction (). Add (R.id.container, mFragment) .commit ().

Dadurch wird die Aktivität dem Fragment zugeordnet und dem Fragment wird auch eine Ansicht zugeordnet.

Hier sind die resultierenden Lebenszyklusereignisse und andere wichtige Methodenrückgabewerte:

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

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

Um ein Fragment aus einer Aktivität zu entfernen, verwenden Sie: getFragmentManager (). BeginTransaction (). Remove (mFragment) .commit ().

Dadurch wird jegliche Zuordnung zu einer Ansicht oder zu einer Aktivität entfernt.

Hier sind die resultierenden Lebenszyklusereignisse und andere wichtige Methodenrückgabewerte:

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

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

Ich habe das Fragment hier erneut hinzugefügt

Um ein hinzugefügtes Fragment von einer Aktivität zu trennen, verwenden Sie: getFragmentManager (). BeginTransaction (). Detach (mFragment) .commit ().

Dadurch wird jede Zuordnung zu einer Ansicht entfernt, die Zuordnung zur Aktivität bleibt jedoch erhalten.

Hier sind die resultierenden Lebenszyklusereignisse und andere wichtige Methodenrückgabewerte:

onPause()                             
onStop()                              
onDestroyView()                      

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

Um ein Fragment, das von der Aktivität getrennt wurde, erneut anzuhängen, verwenden Sie: getFragmentManager (). BeginTransaction (). Attach (mFragment) .commit ().

Dadurch wird eine neue Ansicht erstellt, die dem Fragment zugeordnet werden soll, und die Aktivitätszuordnung wird beibehalten.

Hier sind die resultierenden Lebenszyklusereignisse und andere wichtige Methodenrückgabewerte:

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

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

Andere wichtige Dinge, die Sie beachten sollten: Wenn Sie ein Fragment trennen und dann versuchen, es erneut mit add () anstatt mit attach () hinzuzufügen, scheint sich nichts zu ändern.

Wenn Sie versuchen, ein Fragment hinzuzufügen, das mit remove () entfernt wurde, indem Sie attach () anstelle von add () verwenden, scheint sich nichts zu ändern.

Wenn getView () null zurückgibt, enthält das Fragment möglicherweise noch interne Verweise auf die zuletzt erstellte Ansicht. Diese Ansicht ist nicht mehr gültig und sollte nicht verwendet werden.

Stephen
quelle
1
Gute Arbeit. Es schien jedoch sehr interessant zu sein, das erneute Anhängen und erneute Hinzufügen nach dem Entfernen des Fragments den gleichen Effekt zu erzielen.
Stdout
9
Es stellte sich also heraus, dass "attach ()" onAttach () nicht aufruft. "remove ()" ruft onDetach () nicht auf.
KunYu Tsai
1
Einige dieser Lebenszyklusereignisse können sich geringfügig ändern, wenn Sie Transaktionen im Backstack behalten.
stdout