2012-06-02 2 views
162

が、私はプログラムで追加の断片を持つ活性を有すると言うbackstackに戻って、前のフラグメントに行きますかはプログラム

私はTrigger back-button functionality on button click in Androidが見つかりましたが、私は戻ってキーイベントをシミュレートすることは、それについて移動する(と私はそれはどちらか動作させることはできません)正しい方法ではないと思っています:

dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK)); 

だけfinish()を呼び出します私が興味を持っていないアクティビティを閉じます。

これについてもっと良い方法がありますか?提供された他の回答については詳しく説明しgetFragmentManager().popBackStack()メソッド(から選択するには、いくつかがある)

http://developer.android.com/reference/android/app/FragmentManager.html#popBackStack()

答えて

265

見て、これは(活動中に置かれ)私のソリューションです:

@Override 
public void onBackPressed(){ 
    FragmentManager fm = getFragmentManager(); 
    if (fm.getBackStackEntryCount() > 0) { 
     Log.i("MainActivity", "popping backstack"); 
     fm.popBackStack(); 
    } else { 
     Log.i("MainActivity", "nothing on backstack, calling super"); 
     super.onBackPressed(); 
    } 
} 
+71

'getFragmentManager()。popBackStackImmediate();'トリックを行いました。ありがとう。 –

+0

どこにこの方法を入れますか?私のタブリスナーで? – rasen58

+1

コードを見ることなく、言うことは難しいですが、現在のフラグメントを "閉じる"して前のフラグメントに戻したいときに実行されるコードのセクションに入るはずです。 – stuckless

105

+5

、なぜそれが起こっているのですか?フラグメントの例では、http://developer.android.com/training/basics/fragments/index.html彼らはonbackpressedイベントを上回っていませんが、フラグメントをバックスタックすることができます。 私はこれを使用しました\t trasaction.addToBackStack(null);何も起こりません。 理由を説明できますか? –

+0

@MurtazaHussainもしあなたがこれについて助けを望むなら、あなたはおそらく新しい質問をするべきです。より多くのコードを見ることなく何が起こっているのかを見るのは少し難しいです。 –

+2

私の場合は、スタックに最初のフラグメントだけがあるときに、アクティビティを呼び出すために 'fm.getBackStackEntryCount()> 1'を実行しなければなりませんでした。 –

21

フラグメントを更新/追加する場合は、.addToBackStack()を含める必要があります。

その後

getSupportFragmentManager().beginTransaction() 
    .add(detailFragment, "detail") // Add this transaction to the back stack (name is an optional name for this back stack state, or null). 
    .addToBackStack(null) 
    .commit(); 

我々は断片を更新/追加し、現在の画面に戻って移動した場合getFragments.popBackStackImmediate()はtrueを返します与えれば。

1

次のコードを使用して、プログラムによって前のフラグメントに戻ります。

if (getFragmentManager().getBackStackEntryCount() > 0) 
{ 
      getFragmentManager().popBackStack(); 
      return; 
} 
super.onBackPressed(); 
15

replace() 2つのことを行います。あなたは

  • が同じコンテナ
  • に新しい断片(B)を追加示さコンテナ(C)から現在追加断片(A)を取り外し

    1. これらの2つの操作は、バックスタックレコード/トランザクションとして保存されます。フラグメントAはcreated状態にとどまり、そのビューは破棄されることに注意してください。

      今すぐpopBackStack()は、BackStackに追加した最後のトランザクションを元に戻します。

      2つの段階だろう。この場合、この後にC

    を追加

    1. 削除B C
    2. から、フラグメントBはdetachedになり、あなたが守らなかった場合その参照は、ガベージコレクションされます。

      FragmentBはcreatedの状態のままだったので、質問の最初の部分にはonCreate()コールはありません。そして、質問の第二部分への答えはもう少しです。

      最初に、BackstackにFragmentsを実際に追加しないでください。FragmentTransactionsを追加することを理解することが重要です。だから、あなたが「フラグメントBと置き換えてフラグメントAをバックスタックに追加する」と考えると、この操作全体をバックスタックに実際に追加します。すなわち、の置換を2つのアクションで構成します。

      次に、この置換を含むトランザクションがポップされます。だからあなたは断片Aを飛ばしているわけではない、あなたは「Aを取り除いてBを加える」ことを逆転している。逆は「Bを取り除いてAを加える」。

      最後に、FragmentManagerが認識しているBがないので、最後のステップでAをBに置き換えると、Bは早いライフサイクルメソッド-とonCreate()を実行する必要があります。

      以下のコードは何が起こっているかを示しています。

      FragmentManager fm = getFragmentManager(); 
      FragmentA fragmentA = new FragmentA(); 
      FragmentB fragmentB = new FragmentB(); 
      
      // 1. Show A 
      fm.beginTransaction() 
          .add(fragmentA, R.id.container) 
          .commit(); 
      
      // 2. Replace A with B 
      // FragmentManager keeps reference to fragmentA; 
      // it stays attached and created; fragmentB goes 
      // through lifecycle methods onAttach(), onCreate() 
      // and so on. 
      fm.beginTransaction() 
          .replace(fragmentB, R.id.container) 
          .addToBackstack(null) 
          .commit(); 
      
      // 2'. Alternative to replace() method 
      fm.beginTransaction() 
          .remove(fragmentA) 
          .add(fragmentB, R.id.container) 
          .addToBackstack(null) 
          .commit(); 
      
      // 3. Reverse (2); Result - A is visible 
      // What happens: 
      // 1) fragmentB is removed from container, it is detached now; 
      //  FragmentManager doesn't keep reference to it anymore 
      // 2) Instance of FragmentA is placed back in the container 
      // Now your Backstack is empty, FragmentManager is aware only 
      // of FragmentA instance 
      fm.popBackStack(); 
      
      // 4. Show B 
      // Since fragmentB was detached, it goes through its early 
      // lifecycle methods: onAttach() and onCreate(). 
      fm.beginTransaction() 
          .replace(fragmentB, R.id.container) 
          .addToBackstack(null) 
          .commit(); 
      
    3

    これらの行をonBackPressed()メソッドに追加します。あなたが戻ってスタック上の任意の断片を持っている場合popBackStackImmediateは()メソッドは、バック前のフラグメントにあなたを取得します `

    if(getFragmentManager().getBackStackEntryCount() > 0){ 
        getFragmentManager().popBackStackImmediate(); 
    } 
    else{ 
        super.onBackPressed(); 
    } 
    

    `

    0

    閉じたいときに、このソリューションは、下のバーに基づくフラグメントのナビゲーションのために完璧に動作しますメインのフラグメントでバックプレスされたときのアプリ。

    一方、私のコードで "DetailedPizza"と定義されているセカンダリフラグメント(フラグメント内のフラグメント)を開いているときは、それ以前のプライマリフラグメントの状態が返されます。乾杯!背面に

    インサイド活動この置く押さ:

    Fragment home = getSupportFragmentManager().findFragmentByTag("DetailedPizza"); 
    
        if (home instanceof FragmentDetailedPizza && home.isVisible()) { 
         if (getFragmentManager().getBackStackEntryCount() != 0) { 
          getFragmentManager().popBackStack(); 
         } else { 
          super.onBackPressed(); 
         } 
    
        } else { 
         //Primary fragment 
         moveTaskToBack(true); 
        } 
    

    をそして、このような他の断片起動:ちょうどあなたが望むどのbackstackすることの断片を追加し、そのフラグメントは再び来るようにするには

    Fragment someFragment = new FragmentDetailedPizza(); 
        FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
        transaction.replace(R.id.container_body, someFragment, "DetailedPizza"); 
        transaction.addToBackStack("DetailedPizza"); 
        transaction.commit(); 
    
    1

    を例:

    button.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         Fragment fragment = new LoginFragment(); 
         //replacing the fragment 
         if (fragment != null) { 
          FragmentTransaction ft = ((FragmentActivity)getContext()).getSupportFragmentManager().beginTransaction(); 
          ft.replace(R.id.content_frame, fragment); 
          ft.addToBackStack("SignupFragment"); 
          ft.commit(); 
         } 
        } 
    }); 
    

    上記の場合、私はを開いていますButton buttonを押すと、ユーザーはSignupFragmentになります。したがってaddToBackStack(TAG)が呼び出された場合、TAG = "SignupFragment"の場合、LoginFragmentに戻るボタンが押された場合、SignUpFragmentに戻ります。

    ハッピーコーディング!