7

Activity3 つの Fragments があり、それらをAB、およびCと呼びます。Fragment Aは Activity で呼び出されonCreate()ます。

FragmentA fragA = new FragmentA();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.activity2_layout, fragA, "A");
transaction.commit();

また、特定のボタンが押されたときにフラグメントBまたはCに置き換えられ、FragmentTransaction が呼び出されますaddToBackStack()

FragmentB fragB = new FragmentB(); //or C
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.activity2_layout, fragB, "B");  //or C
transaction.addToBackStack("B"); //or C
transaction.commit();

Fragment しかし、私がBを 3 回続けて呼び出したとしましょう。同時に、これを可能にしたい: Bが呼び出された > Cが呼び出された > Bが呼び出された - しかし、戻ろうとすると、( B < C < B )の代わりにBを 1 回だけ ( C < B )開きたい. したがって、基本的には最初の backStack を新しいもので削除します。

4

2 に答える 2

13

How to resume Fragment from BackStack if existsから、クエリと非常によく似ている可能性があります。

コミットによって提供されたトランザクション名または ID のいずれかに基づいてバックスタックをポップする方法があります (たとえば、Thijs が既に述べたようにフラグメントのクラス名を使用するため):

String backStateName = fragment.getClass().getName();

バックスタックへの追加:

FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();

ポップ時:

getSupportFragmentManager().popBackStackImmediate (backStateName, 0); 

したがって、フラグメントを置き換える前に、次のようにバックスタックで存在を確認できます。

boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);

if (!fragmentPopped){ //fragment not in back stack, create it.
    ...
    ...
    ft.addToBackStack(backStateName);
    ft.commit();
}

詳細については、上記の質問と受け入れられた回答を確認してください。

于 2015-11-18T05:27:40.753 に答える
1

私はあなたの質問の 1 つ、つまりhow can I prevent it from stacking on to it self?、少し前に私自身のプロジェクトの 1 つを解決しました。これは私がそこで使用した正確なコードでした:

public void setContent(@NonNull Fragment fragment, boolean addToBackStack) {
    Fragment current = getSupportFragmentManager().findFragmentById(R.id.main_content);
    if (current == null || !current.getClass().equals(fragment.getClass())) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (addToBackStack) {
            transaction.addToBackStack(null).add(R.id.main_content, fragment).commit();
        } else {
            transaction.replace(R.id.main_content, fragment).commit();
        }
    }
}

このコードが行うことは、現在表示されている Fragment がどのクラスであるかをチェックし、それを置き換えたいフラグメントと比較することです。それらが同じであれば、何もしません。このコードは、次のようにニーズに合わせて形作ることができます

Fragment newFragment = new FragmentB(); //OR FragmentC
Fragment current = getSupportFragmentManager().findFragmentById(R.id.activity2_layout);
if (!current.getClass().equals(newFragment.getClass())) {

    //POP BACKSTACK HERE LIKE EXPLAINED BELOW

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    final String tag = newFragment.getClass().getSimpleName();
    transaction.addToBackStack(tag);
    transaction.add(R.id.activity2_layout, newFragment, tag);
    transaction.commit();
} else {
    //THROW AN ERROR OR SOMETHING, HANDLE IT BEING THE SAME
}

一度に特定のタイプのフラグメントが 1 つだけ存在することを確認するには、同じフラグメントが最初に出現する前までバックスタックをポップすることでおそらく達成できます。このためのコードは書いていませんが、その機能を実装するのはそれほど難しくありません。自分でそれを理解できない場合は、私に知らせてください。例を書いてみます:)

于 2015-11-17T14:18:46.070 に答える