バックスタックから特定のフラグメントを削除する際に問題があります。私のシナリオは次のようになります。Fragment-1はFragment-2に置き換えられ、Fragment-2はFragment-3に置き換えられます。
呼び出し順序;フラグメント-1->フラグメント-2->フラグメント-3。
Fragment-3が画面に表示されている状態で[戻る]ボタンをクリックすると、行きたい
フラグメント-1。つまり、バックスタックからフラグメント-2を削除したいということです。
これを行う方法 ?
バックスタックには、Fragment
sはありませんが、FragmentTransaction
sがあります。 popBackStack()
を実行すると、トランザクションが再度適用されますが、逆方向に適用されます。これは、(毎回addToBackStackTrace(null)
と仮定して)バックスタックにあることを意味します
1->2
2->3
2番目のトランザクションをバックスタックに追加しない場合、結果はバックスタックがちょうど
1->2
そして、戻るボタンを押すと、2->1
は、フラグメント2が存在しないためにエラーになります(フラグメント3にいます)。
最も簡単な解決策は、2から3に進む前にバックスタックをポップすることです
//from fragment-2:
getFragmentManager().popBackStack();
getFragmentManager().beginTransaction()
.replace(R.id.container, fragment3)
.addToBackStack(null)
.commit();
ここでは、フラグメント2からフラグメント1に戻り、次にフラグメント3に直接進みます。この方法で、戻るボタンを押すと3から1に戻ります。
あなたと非常によく似たシナリオがありました。私の解決策は、私が持っていたbackStackトランザクションの量をチェックするだけでした。
トランザクションが0を超える場合は、すぐにポップするので、戻るときにスキップします。
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStackImmediate();
}
...
fragmentTransaction.replace(R.id.main_fragment, newFrag, MAIN_FRAGMENT_TAG);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();
これは成功します:
A-> B(戻る)-> Aに戻る
A-> B-> C(戻る)-> Aに戻る
唯一の欠点は、フラグメントCに進む前にフラグメントAが表示されるクイックフラッシュがあることです。
Fragment3を表示するためのFragmentTransactionのadd()
メソッドの代わりに、同じアクティビティで3つすべてのフラグメントを追加/起動する場合は、FragmentTransactionのreplace()
メソッドを使用します(Fragment2をFragment3に置き換えます)。 replace
メソッドは、新しいフラグメントを追加する前に、現在のフラグメントをバックスタックから削除します。別のアクティビティからFragment3を起動しているため、replace()
を使用できない場合、または使用したくない場合は、新しいアクティビティを開始する前にFragment2をバックスタックから削除します(fragment3が追加されます)。
// in Fragment2, before adding Fragment3:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.remove(this) // "this" refers to current instance of Fragment2
.commit();
fragmentManager.popBackStack();
// now go ahead and launch (add) fragment3
// if fragment3 is launched from a different activity,
// start that activity instead
fragmentManager.beginTransaction()
.add(R.id.a_container_view_in_activity, new Fragment3(),
Fargment3.FRAGMENT3_ID)
.commit();
フラグメントA-> フラグメントBのコード:
追加フラグメント[〜#〜] a [〜#〜] in BackStack of Fragments
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout_container, new fragmentB());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
フラグメントB-> フラグメントCのコード:
追加しないフラグメント[〜#〜] b [〜#〜] in BackStackフラグメント
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout_container, new fragmentC());
fragmentTransaction.commit();
A-> B-> Cおよびwhile returningC-> Aあなたが例外として。
それがあなたを助けることを願っています。
FragmentTransaction
からバック状態に追加し、FragmentManager
popメソッドを使用してバックスタックから削除します。
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove(myFrag);
trans.commit();
manager.popBackStack();
[〜#〜] or [〜#〜]
単純に、フラグメントスタックに追加するフラグメントをスキップできるため、Fragment-3
それはFragment-1
更新済み:
アニメーションを無効にするには、onCreateAnimation
メソッドをオーバーライドする必要があります...
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
if (disableAnim) {
Animation a = new Animation() {};
a.setDuration(0);
return a;
}
return super.onCreateAnimation(transit, enter, nextAnim);
}
for (int i = 0; i < mFragmentManager.getBackStackEntryCount(); i++) {
currentFragment = mFragmentManager.getFragments().get(i);
if (!(currentFragment instanceof ParticularFragment))
mFragmentManager.popBackStack();
else
break;
}