add()、replace()、およびaddToBackStack()の違い


300

これらのメソッドの呼び出しの主な違いは何ですか?

fragmentTransaction.addToBackStack(name);
fragmentTransaction.replace(containerViewId, fragment, tag);
fragmentTransaction.add(containerViewId, fragment, tag);

既存のフラグメントを置き換え、フラグメントをアクティビティ状態に追加し、アクティビティをバックスタックに追加するとはどういう意味ですか?

次に、でfindFragmentByTag()、このメソッドはadd()/ replace()メソッドまたはメソッドによって追加されたタグを検索しaddToBackStack()ますか?

回答:


331

1) fragmentTransaction.addToBackStack(str);

説明 -このトランザクションをバックスタックに追加します。これは、トランザクションがコミットされた後に記憶され、後でスタックからポップされたときにその操作を元に戻すことを意味します。

2) fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)

説明 -コンテナーに追加された既存のフラグメントを置き換えます。これは基本的に、同じcontainerViewIdで追加された現在追加されているすべてのフラグメントに対してremove(Fragment)を呼び出し、次にここで指定された同じ引数でadd(int、Fragment、String)を呼び出すことと同じです。

3) fragmentTransaction.add(int containerViewId, Fragment fragment, String tag)

説明 -フラグメントをアクティビティー状態に追加します。このフラグメントは、オプションでそのビュー(Fragment.onCreateViewがnull以外を返す場合)をアクティビティのコンテナービューに含めることもできます。

既存のフラグメントを置き換え、フラグメントをアクティビティ状態に追加し、アクティビティをバックスタックに追加するとはどういう意味ですか?

実行状態のすべてのアクティビティが保持されるスタックがあります。フラグメントはアクティビティに属します。したがって、それらを追加して、アクティビティに埋め込むことができます。

1つのアクティビティで複数のフラグメントを組み合わせて、マルチペインUIを構築し、フラグメントを複数のアクティビティで再利用できます。これは、フラグメントコンテナーをさまざまなレイアウトで定義した場合に本質的に役立ちます。任意のレイアウトで他のフラグメントに置き換えるだけです。

現在のレイアウトに移動すると、コンテナーのIDがあり、必要なフラグメントに置き換えることができます。

popBackStack()メソッドを使用して、backStackの前のフラグメントに戻ることもできます。そのために、あなたは使用してスタック内のそのフラグメントを追加する必要がありaddToBackStack()、その後とcommit()反映します。これは、電流を上にして逆順です。

findFragmentByTagこの検索は、add / replaceメソッドまたはaddToBackStackメソッドによって追加されたタグを検索しますか?

タグの追加方法によって異なります。次に、XMLから拡張されたとき、またはトランザクションに追加されたときに提供されたときに、以前に定義したタグによってフラグメントを見つけます。

参照:FragmentTransaction


2
それで、開始された最初のアクティビティでreplaceメソッドによってフラグメントを追加できますか?
Yohanes AI 2014

(以前にフラグメントは追加されていません)
Yohanes AI '09 / 09/13

2
フラグメントコンテナに複数のフラグメントを含めることができますか?はいの場合、replace()メソッドはどのように動作しますか。そのコンテナーまたはAndroid API内のすべてのフラグメントを置き換える場合、3つの引数(つまり、frgamentContainer、新しいフラグメント、および置き換える相手)を受け入れるメソッドがあります。
2015年

1
@vedいいえ、コンテナに現在存在するすべてのフラグメントを現在のものに置き換えます。
ルーベンジョン、2015

330

間の1つのより多くの重要な違いaddとはreplaceこれです:

replace既存のフラグメントを削除し、新しいフラグメントを追加します。つまり、戻るボタンを押すと、置き換えられたフラグメントonCreateViewが呼び出されて作成されます。一方add、既存のフラグメントを保持して新しいフラグメントを追加すると、既存のフラグメントがアクティブになり、「一時停止」状態にonCreateViewならないため、[戻る]ボタンが押されても、既存のフラグメント(新しいフラグメントが存在する前にあったフラグメント)が呼び出されません。追加されました)。

フラグメントのライフサイクルイベントの面では onPauseonResumeonCreateViewおよびその他のライフ・サイクル・イベントの場合に呼び出されますreplaceが、彼らはの場合に呼び出すことが文句を言いませんadd

編集:彼女がGreenrobotのEventbusのようなイベントバスライブラリのようなものを使用していて、同じフラグメントを再利用してフラグメントを他のviaの上にスタックする 場合は注意が必要ですadd。このシナリオでは、ベストプラクティスに従ってイベントバスをonResumeに登録および登録解除してもonPauseaddフラグメントはこれらのフラグメントライフサイクルメソッドのいずれも呼び出さないため、追加されたフラグメントの各インスタンスでイベントバスがアクティブのままになります。その結果、フラグメントの各アクティブなインスタンスのイベントバスリスナーは同じイベントを処理しますが、これは意図したものとは異なる場合があります。


1
一番上のフラグメントでイベントを処理し、処理が完了した後にcancelEventDelivery()を呼び出すというアプローチも考えられます。cancelEventDelivery()メソッドの詳細については、こちらのgithub.com/greenrobot/EventBus/blob/master/…を
Jeevan

6
私からの+1。現在のフラグメントを新しいフラグメントに置き換えることを知ることは非常に重要です。つまり、フラグメントスタックからポップバックすると、以前のフラグメントが再作成されて元に戻ります。
AndaluZ 2016年

onPause、onResumeはホストアクティビティと密接に関連しています。そして、彼らはフラグメントを置き換えるときに呼び出しませんでした。
Zar E Ahmer

これに追加するだけで、EventBusを使用している場合は、タグを使用してフラグメントを追加し、そのタグからフラグメントをイベントに渡して、とにかくチェックすると、すべてのイベントバスが呼び出され、どれを実行するかを指定するだけです
user2582318

addToBackStack()をadd()またはreplace()メソッドとともに呼び出すことを言及する必要があります。
rahil008

99

アクティビティに2つのフラグメントがあり、アクティビティのレイアウトに各フラグメントでFragmentManager置換/追加する例addToBackstack

置換を使用

Go Fragment1

Fragment1: onAttach
Fragment1: onCreate
Fragment1: onCreateView
Fragment1: onActivityCreated
Fragment1: onStart
Fragment1: onResume

フラグメント2に移動

Fragment2: onAttach
Fragment2: onCreate
Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment2: onCreateView
Fragment2: onActivityCreated
Fragment2: onStart
Fragment2: onResume

ポップフラグメント2

Fragment2: onPause
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
Fragment2: onDetach
Fragment1: onCreateView
Fragment1: onStart
Fragment1: onResume

ポップフラグメント1

Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach

追加を使用

Go Fragment1

Fragment1: onAttach
Fragment1: onCreate
Fragment1: onCreateView
Fragment1: onActivityCreated
Fragment1: onStart
Fragment1: onResume

フラグメント2に移動

Fragment2: onAttach
Fragment2: onCreate
Fragment2: onCreateView
Fragment2: onActivityCreated
Fragment2: onStart
Fragment2: onResume

ポップフラグメント2

Fragment2: onPause
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
Fragment2: onDetach

ポップフラグメント1

Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach

サンプルプロジェクト


1
onPause()以前onStop()にすべてのポップアクションで呼び出されるはずでした か?
iCantC

「add()」と「replace()」を区別する優れた回答ですが、addToBackStack()については欠落しています。Upvote
Shirish Herwade

@ShirishHerwade彼は両方のケースでaddToBackStackで追加と置換の違いを示したと思います。
Cyber​​Shark

38

これはすでに回答済みの古い質問ですが、多分これらの次の例は、受け入れられた回答を補足することができ、私と同じようにAndroidの新しいプログラマーにとって役立つ可能性があります。

オプション1-「addToBackStack()」は使用されません

ケース1A-追加、削除、および[戻る]ボタンをクリック

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()」が常に使用されます

ケース2A-追加、削除、および[戻る]ボタンをクリック

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()」は常に使用されるわけではありません(以下の例では、w / oは使用されないことを示しています)

ケース3A-追加、削除、および[戻る]ボタンのクリック

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

1
十分に。がんばって!
–ulp_fiction

では、フラグメントの戻るボタンの操作はFragmentManager.popBackStack()関数と同じように機能すると言えるでしょうか。
タンタン

すばらしい答えです。これは受け入れられるべき答えです。
Shirish Herwade

25

との基本的な違いはadd()、次のreplace()ように説明できます。

  • add() 単にいくつかのルート要素にフラグメントを追加するために使用されます。
  • replace() 動作は似ていますが、最初は前のフラグメントを削除してから、次のフラグメントを追加します。

私たちが使用している場合我々は、正確な違いを見ることができるaddToBackStack()と共に、add()またはreplace()

add()... onCreateViewの場合、後で戻るボタンを押すと呼び出されることはありませんが、の場合、replace()戻るボタンを押すと... oncreateViewが毎回呼び出されます。


1
前のフラグメントのビューは破棄されないので、add()はAndroidメモリの点でより大きな負担になりますか?
Derekyy 2017

@Derekyyはい、そう思います。
アーピットJ.

探していたもの
parvez rafi

2

最初のフラグメントを追加するとき-> add()メソッドを使用して2番目のフラグメント

 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()を使用する場合

最初のフラグメントから2番目のフラグメントへ、最初の-> 2番目の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 -------------------------- FirstFragment
E/Keshav FirstFragment: onStop --------------------------- FirstFragment
E/Keshav FirstFragment: onDestroyView -------------------- FirstFragment

E/Keshav SecondFragment: onCreateView
E/Keshav SecondFragment: onActivityCreated
E/Keshav SecondFragment: onStart
E/Keshav SecondFragment: onResume

Replace First Fragmentの場合、これらのメソッドは追加で呼び出されます(onPause、onStop、onDestroyViewは追加で呼び出されます)

E / Keshav FirstFragment:onPause

E / Keshav FirstFragment:onStop

E / Keshav FirstFragment:onDestroyView


0

FragmentMangerの関数addおよびreplaceは、次のように説明できます。1. addは、フラグメントバックスタックにフラグメントを追加し、指定したフレームで提供するように表示します。

getFragmentManager.beginTransaction.add(R.id.contentframe,Fragment1.newInstance(),null)

2.replaceは、特定のフレームでフラグメントを別のフラグメントに置き換えることを意味します

getFragmentManager.beginTransaction.replace(R.id.contentframe,Fragment1.newInstance(),null)

2つの間のメインユーティリティは、バックスタックしている場合、置換はフラグメントを更新しますが、追加は前のフラグメントを更新しません。


0

注意すべき重要なこと:

ReplaceとReplace with backstackの違いは、replaceのみを使用するとフラグメントが破棄される(ondestroy()が呼び出される)ことと、replaceをbackstackで使用するとフラグメントのonDestroy()が呼び出されない(つまり、戻るボタンが押されたときにフラグメントが呼び出される)ことです。 onCreateView())


0

add()との違いを示す画像は次のとおりですreplace()

ここに画像の説明を入力してください

そのため、add()メソッドはFragmentContainer内の前のフラグメントの上にフラグメントを追加し続けます。

一方でreplace()メソッドすべてクリアコンテナから前の断片を、その後FragmentContainerでそれを追加します。

addToBackStackとは

addtoBackStackメソッドはadd()およびreplaceメソッドで使用できます。これは、Fragment APIで別の目的を果たします。

目的は何ですか?

Activity APIとは異なり、Fragment APIには、デフォルトでは戻るボタンナビゲーションがありません。前のFragmentに戻りたい場合は、FragmentでaddToBackStack()メソッドを使用します。両方を理解しましょう

ケース1:

getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragmentContainer, fragment, "TAG")
            .addToBackStack("TAG")
            .commit();

ここに画像の説明を入力してください

ケース2:

getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragmentContainer, fragment, "TAG")
            .commit();

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.