Gehen Sie programmgesteuert zum vorherigen Fragment im Backstack zurück


218

Angenommen, ich habe eine Aktivität, bei der Fragmente programmgesteuert hinzugefügt wurden:

private void animateToFragment(Fragment newFragment, String tag) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, newFragment, tag);
    ft.addToBackStack(null);
    ft.commit();
}

Was ist der beste Weg, um zum vorherigen sichtbaren Fragment zurückzukehren?

Ich habe die Trigger-Back-Button-Funktion beim Klicken auf eine Schaltfläche in Android gefunden, aber ich denke, dass die Simulation eines Back-Key-Ereignisses nicht der richtige Weg ist (und ich kann es auch nicht zum Laufen bringen):

dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));

Das Anrufen finish()schließt nur die Aktivität, an der ich nicht interessiert bin.

Gibt es einen besseren Weg, dies zu tun?

Antworten:


354

Schauen Sie sich die getFragmentManager().popBackStack()Methoden an (es stehen mehrere zur Auswahl)

http://developer.android.com/reference/android/app/FragmentManager.html#popBackStack ()


91
getFragmentManager().popBackStackImmediate();hat den Trick gemacht. Vielen Dank.
Aske B.

1
Wo würde ich diese Methode hinstellen? In meinem Tab Listener?
Rasen58

1
Ohne den Code zu sehen, ist es schwer zu sagen ... aber er sollte in den Codeabschnitt gehen, der ausgeführt wird, wenn Sie das aktuelle Fragment "schließen" und zum vorherigen Fragment zurückkehren möchten.
steckenlos

1
Was ist mit getSupportFragmentManager ()
ViliusK

5
Vergessen Sie nicht, "addToBackStack (" tag ")" in Ihren Code einzufügen. "fragmentManager.beginTransaction (). replace (R.id.content_frame, fragment) .addToBackStack (" tag "). commit ();" Wenn Sie addToBackStack (null) schreiben, wird es von selbst behandelt. Wenn Sie jedoch ein Tag angeben, sollten Sie es manuell behandeln.
Khaled Saif

129

Um auf die anderen Antworten einzugehen, ist dies meine Lösung (in einer Aktivität platziert):

@Override
public void onBackPressed(){
    FragmentManager fm = getFragmentManager();
    if (fm.getBackStackEntryCount() > 0) {
        Log.i("MainActivity", "popping backstack");
        fm.popBackStack();
    } else {
        Log.i("MainActivity", "nothing on backstack, calling super");
        super.onBackPressed();  
    }
}

5
und warum passiert das? Im Fragmentbeispiel developer.android.com/training/basics/fragments/index.html überschreiben sie das onbackpressed-Ereignis nicht und können dennoch Fragmente zurückstapeln. Ich habe trasaction.addToBackStack (null) verwendet. aber nichts passiert. Kannst du erklären warum ?
Murtaza Khursheed Hussain

@MurtazaHussain Sie sollten wahrscheinlich eine neue Frage stellen, wenn Sie Hilfe dabei möchten. Es ist ein wenig schwer zu erkennen, was los ist, ohne mehr Code zu betrachten.
Kyle Falconer

2
In meinem Fall musste ich tun fm.getBackStackEntryCount() > 1, um die Aktivität zurückzurufen, wenn nur das erste Fragment im Stapel vorhanden ist.
Facundo Olano

3
Android erledigt dies bereits für Sie: "Wenn sich FragmentTransaction-Objekte auf dem Backstack befinden und der Benutzer die Back-Taste drückt, entfernt der FragmentManager die letzte Transaktion vom Backstack und führt die umgekehrte Aktion aus (z. B. Entfernen eines Fragments, wenn die Transaktion fügte es hinzu). " (Quelle)
Artkoenig

29

Wenn wir die Fragmente aktualisieren / hinzufügen,

Sollte die enthalten .addToBackStack().

getSupportFragmentManager().beginTransaction()
    .add(detailFragment, "detail") // Add this transaction to the back stack (name is an optional name for this back stack state, or null).
    .addToBackStack(null)
    .commit();

Wenn wir danach den getFragments.popBackStackImmediate()Willen geben, wird true zurückgegeben, wenn wir die Fragmente hinzufügen / aktualisieren und zum aktuellen Bildschirm zurückkehren.


7

Fügen Sie diese Zeile Ihrer onBackPressed () -Methode hinzu. Mit der popBackStackImmediate () -Methode kehren Sie zum vorherigen Fragment zurück, wenn sich ein Fragment auf dem Backstack befindet

if(getFragmentManager().getBackStackEntryCount() > 0){
     getFragmentManager().popBackStackImmediate();
}
else{
    super.onBackPressed();
}

`


5

Diese Lösung eignet sich perfekt für die Fragmentnavigation in der unteren Leiste, wenn Sie die App schließen möchten, wenn Sie das primäre Fragment zurückdrücken.

Wenn Sie dagegen das sekundäre Fragment (Fragment in Fragment) öffnen, das in meinem Code als "DetailedPizza" definiert ist, wird der vorherige Status des primären Fragments zurückgegeben. Prost !

Inside Aktivitäten auf dem Rücken gedrückt setzen dies:

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

if (home instanceof FragmentDetailedPizza && home.isVisible()) {
    if (getFragmentManager().getBackStackEntryCount() != 0) {
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
} else {
    //Primary fragment
    moveTaskToBack(true);
}

Und starten Sie das andere Fragment wie folgt:

Fragment someFragment = new FragmentDetailedPizza();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container_body, someFragment, "DetailedPizza");
transaction.addToBackStack("DetailedPizza");
transaction.commit();

3

Diese Antworten funktionieren nicht, wenn ich nicht addToBackStack () zu meiner Fragmenttransaktion hinzugefügt habe, aber Sie können verwenden:

getActivity().onBackPressed();

von Ihrem Fragment einen Schritt zurück;


1

Kehren Sie programmgesteuert mit dem folgenden Code zum vorherigen Fragment zurück.

if ( getFragmentManager().getBackStackEntryCount() > 0) 
{
          getFragmentManager().popBackStack();
          return;
}
super.onBackPressed();

1

Um dieses Fragment wieder zu erhalten, fügen Sie einfach das Fragment zum Backstack hinzu, auf das Sie zurückgedrückt werden möchten. ZB:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Fragment fragment = new LoginFragment();
        //replacing the fragment
        if (fragment != null) {
            FragmentTransaction ft = ((FragmentActivity)getContext()).getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.content_frame, fragment);
            ft.addToBackStack("SignupFragment");
            ft.commit();
        }
    }
});

In dem obigen Fall öffne ich, LoginFragmentwenn Button buttongedrückt wird, gerade ist der Benutzer in SignupFragment. Wenn addToBackStack(TAG)also aufgerufen wird, wo TAG = "SignupFragment", dann, wenn die Zurück-Taste gedrückt wird LoginFragment, kommen wir zurück zu SignUpFragment.

Viel Spaß beim Codieren!


Ich denke, TAG hat keinen Einfluss, es ist vielleicht sogar null.
CoolMind

1

Durch Hinzufügen fragment_tran.addToBackStack(null)des letzten Fragments kann ich zum letzten Fragment zurückkehren.

neues Fragment hinzufügen :

view.findViewById(R.id.changepass).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.container, new ChangePassword());
            transaction.addToBackStack(null);
            transaction.commit();
        }
    });

1

Ich bin hierher gekommen, um die gleiche Idee zu haben, und in der Zwischenzeit habe ich mir eine eigene ausgedacht, die meiner Meinung nach nicht so schlecht ist und mit ViewPager funktioniert.

Ich habe also die onBackPressed-Methode in der übergeordneten Aktivität, die den viewPager enthält, überschrieben und so eingestellt, dass sie immer minus 1 Position zurückgeht, bis sie das erste Fragment erreicht, und dann die Aktivität schließt.

@Override
public void onBackPressed() {
    if(viewPager.getCurrentItem()>0){
        viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
    } else {
        super.onBackPressed();
        this.close();
    }
}

private void close(){
    this.finish();
}

Dies kann zu einem Nachteil führen, da es jedes Mal nur in eine Richtung zurückgeht. Daher funktioniert es möglicherweise nicht gut, wenn Registerkarten vorhanden sind und Sie die Position mit übersprungenen Fragmenten wechseln (wenn Sie von 0 auf 2 gehen und dann zurück drücken, werden Sie angezogen 1 statt 0)

Für meinen Fall, mit 2 Fragmenten in viewPager ohne Tabs, macht es den Job gut.


Eine ähnliche Frage ist bereits beantwortet. stackoverflow.com/questions/10863572/…
AtifSayings

0

Versuchen Sie den folgenden Code:

@Override
    public void onBackPressed() {
        Fragment myFragment = getSupportFragmentManager().findFragmentById(R.id.container);
        if (myFragment != null && myFragment instanceof StepOneFragment) {
            finish();
        } else {
            if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                getSupportFragmentManager().popBackStack();
            } else {
                super.onBackPressed();
            }
        }
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.