web-dev-qa-db-ja.com

フラグメントaddToBackStack()およびpopBackStackImmediate()が機能しない

私は現在、1つのActionBarActivityおよびFragmentsなどのListFragmentを使用して、Android(14 <= SDK <= 21)のアプリケーションを構築しています] _およびMapFragment、これらは単一のFrameLayoutビュー内で交換されます。

ActionBarActivityは自動的にフラグメントAを置換/コミットします。その後、ユーザーがボタンをタップすると、ホスティングアクティビティは新しい異なるフラグメントBを置換/コミットします。私の目標は、ユーザーが戻るボタンを押すとすぐにフラグメントAに戻ることです。

今いくつかのコード。

主な活動

_public class MainActivity extends ActionBarActivity implements StopFragment.OnFragmentInteractionListener,
    StopItemFragment.OnFragmentInteractionListener {
...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        fragmentManager = getFragmentManager();
        fragmentManager.enableDebugLogging(true);
        ...
        if (fragmentManager.findFragmentById(R.id.content_frame) == null) {
            StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
            fragmentManager.beginTransaction()
                .replace(R.id.content_frame, list)
                .addToBackStack(null)
                .commit();
        }
        ...

        @Override
        public void onFragmentInteraction(String id) {
        selectItem(Integer.parseInt(id));
        }


       private void selectItem(int position) {
       StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
       ...
       fragmentManager.beginTransaction()
            .replace(R.id.content_frame, fragment)
            .commit();

       ...
       }
}
_


問題

addToBackStack()が呼び出されても、フラグメントBにいるとき、フラグメントAに戻ることはできません。MainActivityは直接閉じられます。しかし、私は自分でバックスタックを運が悪ければ管理しようとしました。フラグメントがスタック上にあることがわかりますが、popBackStackImmediate()を呼び出すと、フラグメントAがポップアウトされ、フラグメントトランザクションは実行されません。 (最初のバックプレスは何も起こりません、2番目のアクティビティは閉じられます)

FragmentManager logcatも添付します。
http://Pastebin.com/hFLHprL8

26
Emanuele

まだ解決策を探している人のために。

メインのActivityクラス(フラグメントをホストしている)では、onBackPressed()をオーバーライドします。

_@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0 ){
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}
_

FragmentにはonBackPressed()メソッドはなく、このメソッドはactivity専用です。したがって、戻るキーを押すと、activityのデフォルトの動作が表示されます。

前のアクティビティにアクセスするか(存在する場合)、アプリを終了します。

ここで、このメソッドをオーバーライドして、activityに、バックキーを押したときに、バックスタックにフラグメントがある場合、それらをポップアウトするように指示する必要があります(これはaddToBackStack()が来たときです)写真に)。それ以外の場合は、デフォルトの動作に従います。

71
Nicks

これを試してください(注意add not replace fragmentA、およびaddToBackStack() for fragmentB)

StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
        fragmentManager.beginTransaction()
            .add(R.id.content_frame, list)
            .commit();

そして

StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
   ...
   fragmentManager.beginTransaction()
        .replace(R.id.content_frame, fragment)
        .addToBackStack("FragmentB")
        .commit();
6
unchosen

FragmentManagerbeginTransaction()およびcommit()を手動で呼び出す必要がありました。
onBackPressed()をオーバーライドすることで解決します:

@Override
public void onBackPressed() {
    ...
    if (fragmentManager.getBackStackEntryCount() > 1){
        fragmentManager.popBackStackImmediate();
        fragmentManager.beginTransaction().commit();
    } else {
        //handle finish
        finish(); // Closes app
    }
}
5
Emanuele

AddToBackStack()とpopBackStack()で苦労している場合は、単に使用します

FragmentTransaction ft =getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, new HomeFragment(), "Home");
ft.commit();`

OnBackPressed()でのアクティビティで、タグによってファーグメントを見つけてから、あなたのことをしてください

Fragment home = getSupportFragmentManager().findFragmentByTag("Home");

if (home instanceof HomeFragment && home.isVisible()) {
    // do you stuff
}

詳細情報 https://github.com/DattaHujare/NavigationDrawer フラグメントの処理にaddToBackStack()を使用することはありません。

1
Dattu Hujare

popBackStack()popBackStackImmediatly()がbackStackに(ポップしたい)そのフラグメントを追加しなかったという事実が原因です。これを行うには、フラグメントを追加/置換するトランザクションを作成するときにaddToBackStack()を呼び出す必要があります。

0
Pablo Johnson