Wie implementiert man onBackPressed () in Fragmenten?

Gibt es eine Möglichkeit, onBackPressed() in Android Fragment zu implementieren, ähnlich wie wir es in Android Activity implementieren?

Da der Fragment-Lebenszyklus nicht onBackPressed() . Gibt es eine andere alternative Methode, onBackPressed() in Android 3.0-Fragmenten zu onBackPressed() ?

Solutions Collecting From Web of "Wie implementiert man onBackPressed () in Fragmenten?"

Ich triggerse auf diese Weise Override onBackPressed in der Aktivität. Alle FragmentTransaction sind addToBackStack vor dem Commit:

 @Override public void onBackPressed() { int count = getFragmentManager().getBackStackEntryCount(); if (count == 0) { super.onBackPressed(); //additional code } else { getFragmentManager().popBackStack(); } } 

Laut @HaMMeRed Antwort hier ist Pseudocode wie soll es funktionieren. BaseActivity sagen, dass Ihre Hauptaktivität BaseActivity heißt, die BaseActivity hat (wie in SlidingMenu lib Beispiel). Hier sind die Schritte:

Zuerst müssen wir eine Schnittstelle und eine class erstellen, die ihre Schnittstelle implementiert, um eine generische Methode zu haben

  1. Erstellen Sie die classnschnittstelle OnBackPressedListener

     public interface OnBackPressedListener { public void doBack(); } 
  2. Erstellen Sie eine class, die die Fähigkeiten von OnBackPressedListener

     public class BaseBackPressedListener implements OnBackPressedListener { private final FragmentActivity activity; public BaseBackPressedListener(FragmentActivity activity) { this.activity = activity; } @Override public void doBack() { activity.getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); } } 
  3. Wir arbeiten nun an unserem Code BaseActivity und seinen Fragmenten

  4. Erstellen Sie einen privaten Listener oberhalb Ihrer class BaseActivity

     protected OnBackPressedListener onBackPressedListener; 
  5. Methode zum BaseActivity Listeners in BaseActivity

     public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { this.onBackPressedListener = onBackPressedListener; } 
  6. in override onBackPressed implementieren so etwas

     @Override public void onBackPressed() { if (onBackPressedListener != null) onBackPressedListener.doBack(); else super.onBackPressed(); 
  7. In Ihrem Fragment in onCreateView sollten Sie unseren Listener hinzufügen

     @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { activity = getActivity(); ((BaseActivity)activity).setOnBackPressedListener(new BaseBackPressedListener(activity)); View view = ... ; //stuff with view return view; } 

Voila, jetzt, wenn Sie zurück in das Fragment klicken, sollten Sie Ihre benutzerdefinierte Methode zurück zu fangen.

Dies funktionierte für mich: https://Stackoverflow.com/a/27145007/3934111

 @Override public void onResume() { super.onResume(); if(getView() == null){ return; } getView().setFocusableInTouchMode(true); getView().requestFocus(); getView().setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){ // handle back button's click listener return true; } return false; } }); } 

Wenn Sie diese Art von functionalität YourBackPressed müssen Sie diese in Ihrer Aktivität überschreiben und dann eine YourBackPressed Schnittstelle zu all Ihren Fragmenten hinzufügen, die Sie bei jedem Drücken der Zurück-Taste auf dem entsprechenden Fragment aufrufen.

Edit: Ich möchte meine vorherige Antwort anhängen.

Wenn ich das heute machen würde, würde ich eine Sendung oder möglicherweise eine georderte Sendung verwenden, wenn ich erwarte, dass andere Panels im Einklang mit dem Hauptinhaltsfenster aktualisiert werden.

LocalBroadcastManager in der Support-Bibliothek kann dabei helfen, und Sie senden nur die Sendung in onBackPressed und abonnieren Sie in Ihren onBackPressed Fragmenten. Ich denke, Messaging ist eine entkoppelte Implementierung und würde besser skalieren, also wäre es jetzt meine offizielle Implementierungsempfehlung. Benutze einfach die Intent -Aktion als Filter für deine Nachricht. Sende dein neu erstelltes ACTION_BACK_PRESSED , sende es von deiner Aktivität und höre in den relevanten Fragmenten danach.

Nichts davon ist einfach zu implementieren und wird auch nicht optimal funktionieren.

Fragmente haben einen Methodenaufruf onDetach, der die Aufgabe erledigt.

 @Override public void onDetach() { super.onDetach(); PUT YOUR CODE HERE } 

Dies wird den Job tun.

Ich denke, die beste Lösung ist Create simple interface:

 public interface IOnBackPressed { /** * If you return true the back press will not be taken into account, otherwise the activity will act naturally * @return true if your processing has priority if not false */ boolean onBackPressed(); } 

Und in deiner Aktivität

 public class MyActivity extends Activity { @Override public void onBackPressed() { Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_container); if (!(fragment instanceof IOnBackPressed) || !((IOnBackPressed) fragment).onBackPressed()) { super.onBackPressed(); } } ... } 

Endlich in deinem Fragment:

 public class MyFragment extends Fragment implements IOnBackPressed{ @Override public boolean onBackPressed() { if (myCondition) { //action not popBackStack return true; } else { return false; } } } 

addToBackStack Sie einfach addToBackStack während Sie zwischen Ihren Fragmenten wie addToBackStack :

 fragmentManager.beginTransaction().replace(R.id.content_frame,fragment).addToBackStack("tag").commit(); 

Wenn Sie addToBackStack(null) schreiben, wird es von selbst behandelt, aber wenn Sie ein Tag addToBackStack(null) , sollten Sie es manuell behandeln.

Da diese Frage und einige Antworten mehr als fünf Jahre alt sind, möchte ich meine Lösung teilen. Dies ist eine Fortsetzung und Modernisierung der Antwort von @oyenigun

UPDATE: Am Ende dieses Artikels habe ich eine alternative Implementierung hinzugefügt, die eine abstrakte Fragment-Erweiterung verwendet, die die Aktivität überhaupt nicht beinhaltet, was für jeden mit einer komplexeren Fragmenthierarchie mit verschachtelten Fragmenten nützlich wäre, die ein unterschiedliches Zurückverhalten erfordern.

Ich musste dies implementieren, weil einige der Fragmente, die ich verwende, kleinere Ansichten haben, die ich mit der Zurück-Schaltfläche abbrechen möchte, wie kleine Informationsansichten, die auftauchen usw., aber das ist gut für jeden, der das Verhalten von der Zurück-Knopf in Fragmenten.

Definieren Sie zuerst eine Schnittstelle

 public interface Backable { boolean onBackPressed(); } 

Diese Schnittstelle, die ich Backable (ich bin ein Verfechter für Namenskonventionen), habe eine einzige Methode onBackPressed() , die einen boolean Wert zurückgeben muss. Wir müssen einen booleschen Wert erzwingen, weil wir wissen müssen, ob das Zurück-Drücken das Zurück-Ereignis “absorbiert” hat. Die Rückgabe von ” true bedeutet, dass true Fall ist und keine weitere Aktion erforderlich ist. Andernfalls bedeutet ” false , dass die standardmäßige Zurückaktion weiterhin ausgeführt werden muss. Diese Schnittstelle sollte eine eigene Datei sein (vorzugsweise in einem separaten Paket namens interfaces ). Denken Sie daran, dass das Trennen Ihrer classn in Pakete eine gute Übung ist.

Zweitens, finde das oberste Fragment

Ich habe eine Methode erstellt, die das letzte Fragment Objekt im Backstack zurückgibt. Ich verwende Tags … wenn Sie IDs verwenden, nehmen Sie die notwendigen Änderungen vor. Ich habe diese statische Methode in einer Utility-class, die sich mit Navigationszuständen usw. beschäftigt, aber natürlich, setze sie dort hin, wo sie am besten zu dir passt. Zur Erbauung habe ich mir eine class namens NavUtils .

 public static Fragment getCurrentFragment(Activity activity) { FragmentManager fragmentManager = activity.getFragmentManager(); if (fragmentManager.getBackStackEntryCount() > 0) { String lastFragmentName = fragmentManager.getBackStackEntryAt( fragmentManager.getBackStackEntryCount() - 1).getName(); return fragmentManager.findFragmentByTag(lastFragmentName); } return null; } 

ArrayOutOfBoundsException Sie sicher, dass die Anzahl der ArrayOutOfBoundsException größer als 0 ist, andernfalls kann eine ArrayOutOfBoundsException zur Laufzeit ausgetriggers werden. Wenn es nicht größer als 0 ist, gebe null zurück. Wir werden später nach einem Nullwert suchen …

Drittens: Implementiere ein Fragment

Implementieren Sie die Backable Schnittstelle in dem Fragment, in dem Sie das Verhalten der Zurückschaltfläche überschreiben müssen. Fügen Sie die Implementierungsmethode hinzu.

 public class SomeFragment extends Fragment implements FragmentManager.OnBackStackChangedListener, Backable { ... @Override public boolean onBackPressed() { // Logic here... if (backButtonShouldNotGoBack) { whateverMethodYouNeed(); return true; } return false; } } 

onBackPressed() in der onBackPressed() Überschreibung die von Ihnen benötigte Logik ein. Wenn Sie möchten, dass die Zurück-Schaltfläche nicht den Back-Stack (Standardverhalten) aufruft, geben Sie true zurück , dass Ihr Back-Event absorbiert wurde. Andernfalls gebe false zurück.

Zu guter Letzt, in Ihrer Aktivität …

onBackPressed() die onBackPressed() -Methode und fügen Sie ihr folgende Logik hinzu:

 @Override public void onBackPressed() { // Get the current fragment using the method from the second step above... Fragment currentFragment = NavUtils.getCurrentFragment(this); // Determine whether or not this fragment implements Backable // Do a null check just to be safe if (currentFragment != null && currentFragment instanceof Backable) { if (((Backable) currentFragment).onBackPressed()) { // If the onBackPressed override in your fragment // did absorb the back event (returned true), return return; } else { // Otherwise, call the super method for the default behavior super.onBackPressed(); } } // Any other logic needed... // call super method to be sure the back button does its thing... super.onBackPressed(); } 

Wir holen das aktuelle Fragment in den Backable , führen dann eine Backable durch und ermitteln, ob es unsere Backable Schnittstelle implementiert. Wenn dies der Fall ist, bestimmen Sie, ob das Ereignis absorbiert wurde. Wenn dies der onBackPressed() , sind wir mit onBackPressed() und können zurückkehren. Ansonsten behandle es wie einen normalen Backpress und rufe die Super-Methode auf.

Zweite Option, die Aktivität nicht einzubeziehen

Manchmal möchten Sie nicht, dass die Aktivität das überhaupt behandelt, und Sie müssen direkt mit dem Fragment umgehen. Aber wer sagt, dass Sie keine Fragmente mit einer Backpress-API haben können? Erweitern Sie einfach Ihr Fragment zu einer neuen class.

Erstellen Sie eine abstrakte class, die Fragment erweitert und die View.OnKeyListner Schnittstelle implementiert …

 import android.app.Fragment; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; public abstract class BackableFragment extends Fragment implements View.OnKeyListener { @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); view.setFocusableInTouchMode(true); view.requestFocus(); view.setOnKeyListener(this); } @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_UP) { if (keyCode == KeyEvent.KEYCODE_BACK) { onBackButtonPressed(); return true; } } return false; } public abstract void onBackButtonPressed(); } 

Wie Sie sehen können, BackableFragment jedes Fragment, das BackableFragment , automatisch Klicks, die die View.OnKeyListener Schnittstelle verwenden. Rufen Sie einfach die abstrakte onBackButtonPressed() -Methode aus der implementierten onKey() -Methode auf, indem Sie die Standardlogik verwenden, um eine Zurück-Schaltfläche zu erkennen. Wenn Sie andere onKey() als die Zurück-Schaltfläche registrieren müssen, müssen Sie unbedingt die super Methode aufrufen, wenn Sie onKey() in Ihrem Fragment überschreiben. onKey() überschreiben Sie das Verhalten in der Abstraktion.

Einfach zu bedienen, einfach erweitern und implementieren:

 public class FragmentChannels extends BackableFragment { ... @Override public void onBackButtonPressed() { if (doTheThingRequiringBackButtonOverride) { // do the thing } else { getActivity().onBackPressed(); } } ... } 

Da die Methode onBackButtonPressed() in der onBackButtonPressed() abstrakt ist, müssen Sie nach der Erweiterung onBackButtonPressed() implementieren. Sie gibt void zurück void da sie nur eine Aktion innerhalb der Fragmentklasse ausführen muss und die Absorption der Druckmaschine nicht an die Aktivität weiterleiten muss. onBackPressed() Sie sicher, dass Sie die Activity onBackPressed() -Methode onBackPressed() , wenn Sie mit der Zurück-Schaltfläche nichts zu tun haben, sonst wird die Zurück-Schaltfläche deaktiviert … und das wollen Sie nicht!

Vorbehalte Wie Sie sehen können, setzt dies den Haupt-Listener auf die Root-Ansicht des Fragments, und wir müssen ihn fokussieren. Wenn in Ihrem Fragment, das diese class erweitert (oder andere innere Fragmente oder Ansichten, die dasselbe haben), Bearbeitungstexte (oder andere Ansichten zum Stehlen von Fokussen) beteiligt sind, müssen Sie das separat behandeln. Es gibt einen guten Artikel über das Erweitern eines EditText , um den Fokus auf einen Backpress zu verlieren.

Ich hoffe, dass jemand das nützlich findet. Glückliche Kodierung.

Die Lösung ist einfach:

1) Wenn Sie eine Basisfragmentklasse haben, die alle Fragmente erweitert, dann fügen Sie diesen Code zu seiner class hinzu, andernfalls erstellen Sie eine solche Basisfragmentklasse

  /* * called when on back pressed to the current fragment that is returned */ public void onBackPressed() { // add code in super class when override } 

2) Überschreiben Sie in Ihrer Activity-class onBackPressed wie folgt:

 private BaseFragment _currentFragment; @Override public void onBackPressed() { super.onBackPressed(); _currentFragment.onBackPressed(); } 

3) Fügen Sie in Ihrer Fragmentklasse Ihren gewünschten Code hinzu:

  @Override public void onBackPressed() { setUpTitle(); } 

Nun, ich habe es so gemacht, und es funktioniert für mich

Einfache Schnittstelle

FragmentOnBackClickInterface.java

 public interface FragmentOnBackClickInterface { void onClick(); } 

Beispielimplementierung

MyFragment.java

 public class MyFragment extends Fragment implements FragmentOnBackClickInterface { // other stuff public void onClick() { // what you want to call onBackPressed? } 

dann überschreiben Sie onBackPressed in Aktivität

  @Override public void onBackPressed() { int count = getSupportFragmentManager().getBackStackEntryCount(); List frags = getSupportFragmentManager().getFragments(); Fragment lastFrag = getLastNotNull(frags); //nothing else in back stack || nothing in back stack is instance of our interface if (count == 0 || !(lastFrag instanceof FragmentOnBackClickInterface)) { super.onBackPressed(); } else { ((FragmentOnBackClickInterface) lastFrag).onClick(); } } private Fragment getLastNotNull(List list){ for (int i= list.size()-1;i>=0;i--){ Fragment frag = list.get(i); if (frag != null){ return frag; } } return null; } 

onBackPressed() bewirkt, dass das Fragment von der Aktivität getrennt wird.

Laut @Sterling Diaz Antwort denke ich, dass er Recht hat. ABER eine Situation wird falsch sein. (zB Bildschirm drehen)

Also, ich denke, wir könnten erkennen, ob isRemoving() Ziele erreicht.

Sie können es bei onDetach() oder onDestroyView() schreiben. Es ist Arbeit.

 @Override public void onDetach() { super.onDetach(); if(isRemoving()){ // onBackPressed() } } @Override public void onDestroyView() { super.onDestroyView(); if(isRemoving()){ // onBackPressed() } } 

Sie sollten wie folgt eine Schnittstelle zu Ihrem Projekt hinzufügen.

 public interface OnBackPressed { void onBackPressed(); } 

Und dann sollten Sie diese Schnittstelle auf Ihrem Fragment implementieren;

 public class SampleFragment extends Fragment implements OnBackPressed { @Override public void onBackPressed() { //on Back Pressed } } 

Und Sie können dieses onBackPressed-Ereignis unter Ihren Aktivitäten onBackPressed-Ereignis wie unten auslösen;

 public class MainActivity extends AppCompatActivity { @Override public void onBackPressed() { Fragment currentFragment = getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - 1); if (currentFragment instanceof OnBackPressed) { ((OnBackPressed) currentFragment).onBackPressed(); } super.onBackPressed(); } } 

Wenn Sie EventBus verwenden, ist es wahrscheinlich eine viel einfachere Lösung:

In deinem Fragment:

 @Override public void onAttach(Activity activity) { super.onAttach(activity); EventBus.getDefault().register(this); } @Override public void onDetach() { super.onDetach(); EventBus.getDefault().unregister(this); } // This method will be called when a MessageEvent is posted public void onEvent(BackPressedMessage type){ getSupportFragmentManager().popBackStack(); } 

und in Ihrer Aktivitätsklasse können Sie definieren:

 @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { EventBus.getDefault().unregister(this); super.onStop(); } // This method will be called when a MessageEvent is posted public void onEvent(BackPressedMessage type){ super.onBackPressed(); } @Override public void onBackPressed() { EventBus.getDefault().post(new BackPressedMessage(true)); } 

BackPressedMessage.java ist nur ein POJO-Objekt

Dies ist sehr sauber und es gibt keine Schnittstelle / Implementierung Ärger.

Wie wäre es mit onDestroyView ()?

 @Override public void onDestroyView() { super.onDestroyView(); } 

Dies ist nur ein kleiner Code, der den Trick macht:

  getActivity().onBackPressed(); 

Hoffe es hilft jemandem 🙂

Sehr kurze und süße Antwort:

 getActivity().onBackPressed(); 

Erklärung des ganzen Szenarios meines Falles:

Ich habe FragmentA in MainActivity, ich öffne FragmentB von FragmentA (FragmentB ist ein Kind oder ein verschachteltes Fragment von FragmentA)

  Fragment duedateFrag = new FragmentB(); FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.container_body, duedateFrag); ft.addToBackStack(null); ft.commit(); 

Wenn Sie nun von FragmentB zu FragmentA getActivity().onBackPressed(); möchten, können Sie einfach getActivity().onBackPressed(); in FragmentB.

Das ist meine Lösung:

in MyActivity.java:

 public interface OnBackClickListener { boolean onBackClick(); } private OnBackClickListener onBackClickListener; public void setOnBackClickListener(OnBackClickListener onBackClickListener) { this.onBackClickListener = onBackClickListener; } @Override public void onBackPressed() { if (onBackClickListener != null && onBackClickListener.onBackClick()) { return; } super.onBackPressed(); } 

und im Fragment:

 ((MyActivity) getActivity()).setOnBackClickListener(new MyActivity.OnBackClickListener() { @Override public boolean onBackClick() { if (condition) { return false; } // some codes return true; } }); 

Implementieren Sie die Methode ft.addToBackStack () nicht, damit Ihre Aktivität nach dem Drücken der Schaltfläche beendet wird.

 proAddAccount = new ProfileAddAccount(); FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.fragment_container, proAddAccount); //fragmentTransaction.addToBackStack(null); fragmentTransaction.commit(); 

Befolgen Sie einfach diese Schritte:

Immer beim Hinzufügen eines Fragments,

 fragmentTransaction.add(R.id.fragment_container, detail_fragment, "Fragment_tag").addToBackStack(null).commit(); 

In der Hauptaktivität überschreiben onBackPressed()

 if (getSupportFragmentManager().getBackStackEntryCount() > 0) { getSupportFragmentManager().popBackStack(); } else { finish(); } 

Um den Zurück-Button in Ihrer App zu bearbeiten,

 Fragment f = getActivity().getSupportFragmentManager().findFragmentByTag("Fragment_tag"); if (f instanceof FragmentName) { if (f != null) getActivity().getSupportFragmentManager().beginTransaction().remove(f).commit() } 

Das ist es!

Beste Lösung,

 import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v7.app.AppCompatActivity; public class BaseActivity extends AppCompatActivity { @Override public void onBackPressed() { FragmentManager fm = getSupportFragmentManager(); for (Fragment frag : fm.getFragments()) { if (frag == null) { super.onBackPressed(); finish(); return; } if (frag.isVisible()) { FragmentManager childFm = frag.getChildFragmentManager(); if (childFm.getFragments() == null) { super.onBackPressed(); finish(); return; } if (childFm.getBackStackEntryCount() > 0) { childFm.popBackStack(); return; } else { fm.popBackStack(); if (fm.getFragments().size() < = 1) { finish(); } return; } } } } } 

Im Aktivitätslebenszyklus behandelt die android Back-Schaltfläche immer die FragmentManager-Transaktionen, wenn wir FragmentActivity oder AppCompatActivity verwendet haben.

Um das Backstack zu behandeln, müssen wir nicht die Backstack-Anzahl oder das Tag behandeln, aber wir sollten den Fokus behalten, während wir ein Fragment hinzufügen oder ersetzen. Finden Sie die folgenden Snippets, um die Back-Button-Fälle zu behandeln,

  public void replaceFragment(Fragment fragment) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); if (!(fragment instanceof HomeFragment)) { transaction.addToBackStack(null); } transaction.replace(R.id.activity_menu_fragment_container, fragment).commit(); } 

Hier werde ich keinen Backstack für mein Homefragment hinzufügen, da dies die Startseite meiner Anwendung ist. Wenn addToBackStack zu HomeFragment hinzugefügt wird, dann wird die App warten, um alle Framents in der Aktivität zu entfernen, dann erhalten wir einen leeren Bildschirm, so dass ich die folgende Bedingung behalte:

 if (!(fragment instanceof HomeFragment)) { transaction.addToBackStack(null); } 

Jetzt können Sie das zuvor hinzugefügte Fragment auf acitvity sehen und die App wird beendet, wenn Sie HomeFragment erreichen. Sie können sich auch die folgenden Snippets ansehen.

 @Override public void onBackPressed() { if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) { closeDrawer(); } else { super.onBackPressed(); } } 

Its just simple if you have An Activity A and you make 3 fragments like B ,C and D.Now if you are in fragment B or C and onBackPressed you want to move on Fragment D every time .Then you have to just Override the onBackPressed() method in main Activity A and also when you jump to any fragment then pass a TAG or name of that fragment by which you recognized that fragment in main Activity A.

I am giving the example of that one by which you can easily understand that….

 if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction().add(R.id.container, new C_fragment(),"xyz").commit(); } 

or if you are moving from fragment B to fragment C..and on back press you want to come on Fragment D…like below

 btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { getActivity().getSupportFragmentManager().beginTransaction().add(R.id.container, new C_frament(), "xyz").commit(); ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Fragment C"); } }); 

Now you have to just override the onBackPressed() method in main activity….like below..

 @Override public void onBackPressed() { FragmentManager fragmentManager =getSupportFragmentManager(); if (((C_fragment) getSupportFragmentManager().findFragmentByTag("xyz")) != null && ((C_fragment) getSupportFragmentManager().findFragmentByTag("xyz")).isVisible()) { Fragment fragment = new D_Fragment(); fragmentManager.beginTransaction().replace(R.id.container, fragment).commit(); getSupportActionBar().setTitle("D fragment "); } else { super.onBackPressed(); } } 

I have used another approach as follows:

  • An Otto event bus to communicate between the Activity and its Fragments
  • A Stack in the Activity containing custom back actions wrapped in a Runnable that the calling fragment defines
  • When onBackPressed is called in the controlling Activity, it pops the most recent custom back action and executes its Runnable . If there’s nothing on the Stack, the default super.onBackPressed() is called

The full approach with sample code is included here as an answer to this other SO question .

public class MyActivity extends Activity {

 protected OnBackPressedListener onBackPressedListener; public interface OnBackPressedListener { void doBack(); } public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { this.onBackPressedListener = onBackPressedListener; } @Override public void onBackPressed() { if (onBackPressedListener != null) onBackPressedListener.doBack(); else super.onBackPressed(); } @Override protected void onDestroy() { onBackPressedListener = null; super.onDestroy(); } 

}

in your fragment add the following, dont forget to implement mainactivity’s interface.

 public class MyFragment extends Framgent implements MyActivity.OnBackPressedListener { @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ((MyActivity) getActivity()).setOnBackPressedListener(this); } @Override public void doBack() { //BackPressed in activity will call this; } } 

I know it’s too late but I had the same problem last week. None of the answers helped me. I then was playing around with the code and this worked, since I already added the fragments.

In your Activity, set an OnPageChangeListener for the ViewPager so that you will know when the user is in the second activity. If he is in the second activity, make a boolean true as follows:

  mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); // Set up the ViewPager with the sections adapter. mViewPager = (ViewPager) findViewById(R.id.pager); mViewPager.setAdapter(mSectionsPagerAdapter); mViewPager.setCurrentItem(0); mViewPager.addOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { // TODO Auto-generated method stub mSectionsPagerAdapter.instantiateItem(mViewPager, position); if(position == 1) inAnalytics = true; else if(position == 0) inAnalytics = false; } @Override public void onPageScrolled(int position, float arg1, int arg2) { // TODO Auto-generated method stub } @Override public void onPageScrollStateChanged(int arg0) { // TODO Auto-generated method stub } }); 

Now check for the boolean whenever back button is pressed and set the current item to your first Fragment:

 @Override public void onBackPressed() { if(inAnalytics) mViewPager.setCurrentItem(0, true); else super.onBackPressed(); } 
 @Override public void onResume() { super.onResume(); getView().setFocusableInTouchMode(true); getView().requestFocus(); getView().setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) { // handle back button replaceFragmentToBackStack(getActivity(), WelcomeFragment.newInstance(bundle), tags); return true; } return false; } }); } 

Ok guys I finally found out a good solution.

In your onCreate() in your activity housing your fragments add a backstack change listener like so:

  fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { List f = fragmentManager.getFragments(); //List f only returns one value Fragment frag = f.get(0); currentFragment = frag.getClass().getSimpleName(); } }); 

(Also adding my fragmenManager is declared in the activities O Now every time you change fragment the current fragment String will become the name of the current fragment. Then in the activities onBackPressed() you can control the actions of your back button as so:

  @Override public void onBackPressed() { switch (currentFragment) { case "FragmentOne": // your code here return; case "FragmentTwo": // your code here return; default: fragmentManager.popBackStack(); // default action for any other fragment (return to previous) } } 

I can confirm that this method works for me.

I had the same problem and I created a new listener for it and used in my fragments.

1 – Your activity should have a listener interface and a list of listeners in it

2 – You should implement methods for adding and removing the listeners

3 – You should override the onBackPressed method to check that any of the listeners use the back press or not

 public class MainActivity ... { /** * Back press listener list. Used for notifying fragments when onBackPressed called */ private Stack backPressListeners = new Stack(); ... /** * Adding new listener to back press listener stack * @param backPressListener */ public void addBackPressListener(BackPressListener backPressListener) { backPressListeners.add(backPressListener); } /** * Removing the listener from back press listener stack * @param backPressListener */ public void removeBackPressListener(BackPressListener backPressListener) { backPressListeners.remove(backPressListener); } // Overriding onBackPressed to check that is there any listener using this back press @Override public void onBackPressed() { // checks if is there any back press listeners use this press for(BackPressListener backPressListener : backPressListeners) { if(backPressListener.onBackPressed()) return; } // if not returns in the loop, calls super onBackPressed super.onBackPressed(); } } 

4 – Your fragment must implement the interface for back press

5 – You need to add the fragment as a listener for back press

6 – You should return true from onBackPressed if the fragment uses this back press

7 – IMPORTANT – You must remove the fragment from the list onDestroy

 public class MyFragment extends Fragment implements MainActivity.BackPressListener { ... @Override public void onAttach(Activity activity) { super.onCreate(savedInstanceState); // adding the fragment to listener list ((MainActivity) activity).addBackPressListener(this); } ... @Override public void onDestroy() { super.onDestroy(); // removing the fragment from the listener list ((MainActivity) getActivity()).removeBackPressListener(this); } ... @Override public boolean onBackPressed() { // you should check that if this fragment is the currently used fragment or not // if this fragment is not used at the moment you should return false if(!isThisFragmentVisibleAtTheMoment) return false; if (isThisFragmentUsingBackPress) { // do what you need to do return true; } return false; } } 

There is a Stack used instead of the ArrayList to be able to start from the latest fragment. There may be a problem also while adding fragments to the back stack. So you need to check that the fragment is visible or not while using back press. Otherwise one of the fragments will use the event and latest fragment will not be closed on back press.

I hope this solves the problem for everyone.

on mainActivity

 protected DrawerHomeActivity.OnBackPressedListener onBackPressedListener; public interface OnBackPressedListener { void doBack(); } public void setOnBackPressedListener(DrawerHomeActivity.OnBackPressedListener onBackPressedListener) { this.onBackPressedListener = onBackPressedListener; } @Override public void onBackPressed() { if (onBackPressedListener != null) { onBackPressedListener.doBack(); } else super.onBackPressed(); } 

on fragment implement base activity/fragment like

 implements DrawerHomeActivity.OnBackPressedListener 

DraweHomeActivity is my base activity write

 ((DrawerHomeActivity) getActivity()).setOnBackPressedListener(this); 

and create method doBack

 @Override public void doBack() { //call base fragment } 

Fragment: Make a BaseFragment placing a method:

  public boolean onBackPressed(); 

Aktivität:

 @Override public void onBackPressed() { List fragments = getSupportFragmentManager().getFragments(); if (fragments != null) { for (Fragment fragment : fragments) { if (!fragment.isVisible()) continue; if (fragment instanceof BaseFragment && ((BaseFragment) fragment).onBackPressed()) { return; } } } super.onBackPressed(); } 

Your activity will run over the attached and visible fragments and call onBackPressed() on each one of them and abort if one of them returns ‘true’ (meaning that it has been handled, so no further actions).