webentwicklung-frage-antwort-db.com.de

Fragment addToBackStack () und popBackStackImmediate () funktionieren nicht

Ich baue gerade eine Anwendung für Android (14 <= ​​SDK <= 21), indem ich eine ActionBarActivity und mehrere Fragments wie ListFragment und MapFragment verwende, die innerhalb einer einzelnen FrameLayout-Ansicht ausgetauscht werden.

Die ActionBarActivity ersetzt das Fragment A automatisch/schreibt es aus. Wenn der Benutzer auf eine Schaltfläche tippt, wird die Hosting-Aktivität ein neues anderes Fragment B ersetzt/festgelegt. Mein Ziel ist es, den Benutzer auf das Fragment A zurückzusetzen, sobald er die Zurück-Taste drückt .

Ein bisschen Code jetzt.

Hauptaktivität

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

       ...
       }
}


Problem

Selbst wenn addToBackStack() aufgerufen wird, kann ich mit Fragment B nicht zu Fragment A zurückkehren. MainActivity ist direkt geschlossen .. Dennoch habe ich versucht, den Back-Stack ohne Erfolg alleine zu verwalten. Ich kann sehen, dass sich das Fragment auf dem Stapel befindet, aber wenn ich popBackStackImmediate() aufrufe, wird Fragment A herausgefahren und die Fragmenttransaktion wird nicht ausgeführt. (Erstes Rückdrücken nichts passiert, zweite Aktivität geschlossen)

Ich füge auch das FragmentManager-Logcat bei:
http://Pastebin.com/hFLHprL8

24
Emanuele

Für diejenigen, die noch nach einer Lösung suchen.

In der Activity-Hauptklasse (die die Fragmente hostet) überschreiben Sie einfach onBackPressed().

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

Es gibt keine onBackPressed()-Methode in fragment, und diese Methode gilt nur für die activity. Wenn Sie also die Zurück-Taste drücken, wird das Standardverhalten von activity angezeigt

sie gelangen entweder zur vorherigen Aktivität (falls vorhanden) oder zur App wird verlassen.

Jetzt müssen wir diese Methode außer Kraft setzen, um der Variable activity mitzuteilen, dass beim Drücken der Zurück-Taste, wenn sich im Back-Stack Fragmente befinden, diese herausgefahren werden (und dies ist, wenn die addToBackStack() im Bild erscheint). Ansonsten folgen Sie dem Standardverhalten.

70
Nicks

Versuchen Sie dies (Anmerkung add not replace für fragmentA und addToBackStack () für fragmentB)

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

und

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

Ich musste beginTransaction() und commit() von FragmentManager manuell aufrufen.
Gelöst durch Überschreiben von onBackPressed():

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

Wenn Sie mit addToBackStack () & popBackStack () kämpfen, verwenden Sie einfach

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

Finden Sie in Ihrer Aktivität In OnBackPressed () heraus, was Sie von Tag zu Tag finden und erledigen Sie dann Ihre Sachen

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

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

Weitere Informationen https://github.com/DattaHujare/NavigationDrawer Ich verwende niemals addToBackStack () zur Behandlung von Fragmenten.

1
Dattu Hujare

der Grund, warum popBackStack() und popBackStackImmediatly() auf die Tatsache zurückzuführen sind, dass Sie dieses Fragment (das Sie platzieren möchten) nicht zum backStack hinzugefügt haben. Dazu müssen Sie zum Zeitpunkt der Transaktion addToBackStack () aufrufen, um Ihr Fragment hinzuzufügen oder zu ersetzen.

0
Pablo Johnson