これは、深くネストされたスタックを離れるときに、フラグメントバックスタックをクリーンアップする正しい方法ですか?
-
22-10-2019 - |
質問
Android互換性ライブラリを使用してフラグメントを実装し、レイアウトサンプルを拡張して、フラグメントに別のフラグメントを発射するボタンが含まれるようにしました。
左側の選択ペインには、5つの選択可能なアイテムがあります - A B C D E
.
それぞれがフラグメントをロードします(経由 FragmentTransaction:replace
)詳細ペイン - a b c d e
今、私はフラグメントを拡張しました e
別のフラグメントをロードするボタンを含む e1
詳細ペインでも。フラグメントでこれをしました e
次のように、sclickメソッド:
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details_frag, newFrag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
次の選択を行う場合:
E - e - e1 - D - E
次に、フラグメント e
詳細ペインにあります。これは大丈夫で、私が欲しいものです。しかし、私がヒットした場合 back
この時点でボタンは何もしません。私はそれを2回クリックする必要があります e1
まだスタックにあります。さらに、クリックした後、OnCreateviewでnullポインターの例外が得られました。
この問題を「解決」するために、いつでも以下を追加しました A B C D E
選択されています:
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
これが正しい解決策であるのか、それとも私が何か違うことをすべきかどうか疑問に思っているだけですか?
解決
さて、これを意図した動作に応じてこれを実現する方法はいくつかありますが、このリンクはすべての最良の解決策を提供するはずであり、驚くことではありません。
http://groups.google.com/group/android-developers/browse_thread/thread/d2a5c203dad6ec42
基本的に、次のオプションがあります
- 最初のバックスタック状態に名前を使用して使用します
FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)
. - 使用する
FragmentManager.getBackStackEntryCount()
/getBackStackEntryAt().getId()
バックスタックの最初のエントリのIDを取得するには、FragmentManager.popBackStack(int id, FragmentManager.POP_BACK_STACK_INCLUSIVE)
. FragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
バックスタック全体をポップすることになっています...そのためのドキュメントは間違っていると思います。 (実際、私はそれがあなたが通り過ぎる場合をカバーしていないと思いますPOP_BACK_STACK_INCLUSIVE
),
他のヒント
すべてのスタックエントリをポップしたくない場合は、他のクリーンソリューション...
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.home_activity_container, fragmentInstance).addToBackStack(null).commit();
これにより、最初にスタックがきれいになり、次に新しいフラグメントがロードされるため、任意のポイントでスタックに単一のフラグメントのみがあります。
ありがとう ヨアヒム 回答、コードを使用して、すべてのバックスタックエントリをクリアします。
// In your FragmentActivity use getSupprotFragmentManager() to get the FragmentManager.
// Clear all back stack.
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < backStackCount; i++) {
// Get the back stack fragment id.
int backStackId = getSupportFragmentManager().getBackStackEntryAt(i).getId();
fm.popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} /* end of for */
私はバックスタックを掃除するためにたくさん研究しました、そして最後に見る トランザクションバックスタックとその管理. 。これが私にとって最適なソリューションです。
// CLEAR BACK STACK.
private void clearBackStack() {
final FragmentManager fragmentManager = getSupportFragmentManager();
while (fragmentManager.getBackStackEntryCount() != 0) {
fragmentManager.popBackStackImmediate();
}
}
上記の方法は、バックスタックのすべてのトランザクションにループし、すぐに1つずつ削除します。
ノート: 上記のコードはいつかうまくいきませんが、私は直面しています anr このコードのおかげで、これを試してはいけません。
アップデート以下のメソッドバックスタックからその「名前」のすべてのフレグメントを削除します。
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack("name",FragmentManager.POP_BACK_STACK_INCLUSIVE);
- 名前が非ヌルの場合、これは探している以前のバックステートの名前です。見つかった場合、その状態までのすべての状態がポップされます。
- pop_back_stack_inclusiveフラグを使用して、指定された状態自体がポップされているかどうかを制御できます。 nullの場合、上部の状態のみがポップされます。
私はwhileループを使用しているコードと同様のコードを使用していますが、すべてのループでエントリカウントを呼び出します...だから私はそれがやや遅いと思います
FragmentManager manager = getFragmentManager();
while (manager.getBackStackEntryCount() > 0){
manager.popBackStackImmediate();
}
// pop back stack all the way
final FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
int entryCount = fm.getBackStackEntryCount();
while (entryCount-- > 0) {
fm.popBackStack();
}