フラグメントのデタッチと削除の違いは何ですか?


118

FragmentTransactionの Androidドキュメントで、2つの非常によく似たメソッドに気づきました:detachremove。そこにある説明は、それぞれをいつ使用するかについての洞察を提供していないようであり、私が言うことができることから、それらは同じように見えます。

では、これら2つの方法の違いは何ですか?

回答:


156

detachメソッドはUIからフラグメントを削除しますが、その状態はフラグメントマネージャーによって維持されます。つまり、変更されたViewHierarchyを使用してattachメソッドを呼び出すことで、このフラグメントを再利用できます。

削除は、フラグメントインスタンスを再接続できないことを意味します。フラグメントトランザクションに再度追加する必要があります。

ソースコメント

Fragmentがデタッチされると、そのonPause、onStop、およびonDestroyViewメソッドが(この順序で)のみ呼び出されることがわかります。一方、フラグメントが削除されると、そのonPause、onStop、onDestroyView、onDestroy、onDetachメソッドが(この順序で)呼び出されます。同様に、アタッチする場合、フラグメントのonCreateView、onStart、およびonResumeメソッドのみが呼び出されます。追加時に、フラグメントのonAttach、onCreate、onCreateView、onStart、onResumeメソッドが(この順序で)呼び出されます。–アディルフセイン


145
Rajdeepの回答に追加すると、a Fragmentdetachedの場合、そのonPauseonStopおよびonDestroyViewメソッドが(この順序で)のみ呼び出されることがわかります。一方、Fragment除去の、onPauseonStoponDestroyViewonDestroy及びonDetach(そのために)メソッドが呼び出されます。同様に、付着FragmentのをonCreateViewonStartおよびonResume方法がのみ呼び出されます。場合や追加FragmentのはonAttachonCreateonCreateViewonStartおよびonResume方法は、(この順番で)と呼ばれます。
Adil Hussain

1
ここで、ダイアンハックボーンとの迅速なQ&Aがあります。では、なぜこのログがあるのですか?FT.detach()が呼び出されたことをどのようにして知っていますか?
Poutrathor 2013

1
どちらが他の利点よりも優れていますか?一方が他方よりも有利な場合の使用例を知りたいですか?常に追加と削除を行いますが、それは悪いことですか?
ネオンワージ

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

アクティビティにデタッチされたフラグメントを再アタッチするには、getFragmentManager()。beginTransaction()。attach(mFragment).commit()を使用します。

これにより、フラグメントに関連付ける新しいビューが作成され、アクティビティの関連付けが維持されます。

結果のライフサイクルイベントとその他の重要なメソッドの戻り値は次のとおりです。

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

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

注意すべきその他の重要事項:Fragmentをデタッチしてから、attach()ではなくadd()を使用して再度追加しようとした場合、何も変更されていないようです。

add()ではなくattach()を使用して、remove()を使用して削除されたフラグメントを追加しようとした場合、何も変更されていないようです。

getView()がnullを返すとき、フラグメントはまだ、最後に作成したビューへの内部参照を持っている可能性があります。このビューは有効ではなくなったため、使用しないでください。


1
よくできました。しかし、フラグメントが削除された後、再接続や再追加を試みても同じ効果があるのは非常に興味深いようです。
stdout 2016年

9
したがって、「attach()」はonAttach()を呼び出さないことがわかりました。"detach()"はonDetach()を呼び出しません。
KunYu Tsai 2017

1
また、トランザクションをバックスタックに保持すると、これらのライフサイクルイベントの一部がわずかに変化する可能性があります。
stdout
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.