プログラムでバックスタックの前のフラグメントに戻る


218

プログラムでフラグメントが追加されたアクティビティがあるとします。

private void animateToFragment(Fragment newFragment, String tag) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, newFragment, tag);
    ft.addToBackStack(null);
    ft.commit();
}

表示されていた前のフラグメントに戻る最良の方法は何ですか?

Androidのボタンクリックでトリガーバックボタン機能を見つけましたが、バックキーイベントをシミュレートすることはそれを回避するための適切な方法ではないと思います(それを機能させることもできません)。

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

電話をかけるfinish()だけで、興味のないアクティビティが閉じられます。

これについてより良い方法はありますか?

回答:


354

getFragmentManager().popBackStack()メソッドを見てください(いくつかの選択肢があります)

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


91
getFragmentManager().popBackStackImmediate();トリックをしました。ありがとう。
Aske B.

1
この方法はどこに置けばよいでしょうか?タブリスナーでは?
rasen58 2012

1
コードを見なければ、言うのは難しいですが、現在のフラグメントを「閉じて」前のフラグメントに戻りたいときに実行されるコードのセクションに移動する必要があります。
スタックレス、

1
何getSupportFragmentManagerについて()
ViliusK

5
コードに「addToBackStack( "tag")」を追加することを忘れないでください。「fragmentManager.beginTransaction()。replace(R.id.content_frame、fragment).addToBackStack( "tag")。commit();」addToBackStack(null)を記述した場合は、それ自体で処理しますが、タグを指定した場合は、手動で処理する必要があります。
Khaled Saif

129

提供された他の回答について詳しく説明するために、これは私の解決策です(アクティビティに配置されます)。

@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();  
    }
}

5
そしてなぜそれが起こっているのですか?断片の例にdeveloper.android.com/training/basics/fragments/index.htmlそれらはonbackpressedイベントをoveridingず、まだ彼らはbackstackフラグメントすることが可能です。trasaction.addToBackStack(null);を使用しました。しかし、何も起こりません。理由を説明できますか?
Murtaza Khursheed Hussain 2013

@MurtazaHussainこれについてサポートが必要な場合は、おそらく新しい質問をする必要があります。より多くのコードを見ないで何が起こっているかを見るのは少し難しいです。
カイルファルコナー2013年

2
私の場合fm.getBackStackEntryCount() > 1、スタックに最初のフラグメントしかないときにアクティビティをコールバックするために実行する必要がありました。
Facundo Olano 2015

3
Androidは既にこれを行っています。「バックスタックにFragmentTransactionオブジェクトがあり、ユーザーが[戻る]ボタンを押すと、FragmentManagerは最新のトランザクションをバックスタックからポップし、逆のアクションを実行します(トランザクションの場合、フラグメントの削除など)。追加されました)。」 (出典)
artkoenig

29

フラグメントを更新/追加するとき、

を含める必要があります.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()、フラグメントを追加または更新すると、willがtrueを返し、現在の画面に戻ります。


7

これらの行をonBackPressed()メソッドに追加します。popBackStackImmediate()メソッドは、バックスタックにフラグメントがある場合、前のフラグメントに戻ります `

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

`


5

このソリューションは、プライマリフラグメントでバックプレスされたときにアプリを閉じたい場合に、ボトムバーベースのフラグメントナビゲーションに対して完全に機能します。

一方、コードで「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);
}

そして、次のような他のフラグメントを起動します。

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

3

フラグメントトランザクションにaddToBackStack()が追加されていない場合、これらの回答は機能しませんが、以下を使用できます。

getActivity().onBackPressed();

任意のフラグメントから1ステップ戻ります。


1

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

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

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();
        }
    }
});

上記の場合、私は、開封しておりますLoginFragment時にButton button押されて、今、ユーザーがありますSignupFragment。あればaddToBackStack(TAG)呼ばれ、どこTAG = "SignupFragment"バックボタンが押されたとき、そしてLoginFragment、我々は戻ってきますSignUpFragment

ハッピーコーディング!


TAGは影響しません。おそらくnullです。
CoolMind 2018

1

fragment_tran.addToBackStack(null)最後のフラグメントを追加することで、最後のフラグメントに戻ることができます。

新しいフラグメントを追加する

view.findViewById(R.id.changepass).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.container, new ChangePassword());
            transaction.addToBackStack(null);
            transaction.commit();
        }
    });

1

私はここに来て同じアイデアを探していましたが、その間私は自分で考えました。

つまり、私がしたことは、viewPagerを保持する親アクティビティのonBackPressedメソッドをオーバーライドし、最初のフラグメントに到達するまで常にマイナス1の位置に戻るように設定して、アクティビティを閉じることです。

@Override
public void onBackPressed() {
    if(viewPager.getCurrentItem()>0){
        viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
    } else {
        super.onBackPressed();
        this.close();
    }
}

private void close(){
    this.finish();
}

これには、毎回左に戻るだけのような落とし穴がある可能性があるため、タブがあり、フラグメントをスキップして位置を切り替えた場合、うまく機能しない可能性があります(0から2に移動してから、戻るキーを押すと、 0の代わりに1)

私のケースでは、タブのないviewPagerに2つのフラグメントがあるため、うまく機能します。


同様の質問はすでに回答されています。 stackoverflow.com/questions/10863572/...
AtifSayings

0

以下のコードを試してください:

@Override
    public void onBackPressed() {
        Fragment myFragment = getSupportFragmentManager().findFragmentById(R.id.container);
        if (myFragment != null && myFragment instanceof StepOneFragment) {
            finish();
        } else {
            if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                getSupportFragmentManager().popBackStack();
            } else {
                super.onBackPressed();
            }
        }
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.