Is there a way in which we can implement onBackPressed()
in Android Fragment similar to the way in which we implement in Android Activity?
As the Fragment lifecycle do not have onBackPressed()
. Is there any other alternative method to over ride onBackPressed()
in Android 3.0 fragments?
since this question and some of the answers are over five years old, let me share my solution. This is a follow-up and modernization to the answer from @oyenigun
UPDATE: At the bottom of this article, I added an alternative implementation using an abstract Fragment extension that won't involve the Activity at all, which would be useful for anyone with a more complex fragment hierarchy involving nested fragments that require different back behavior.
I needed to implement this because some of the fragments I use have smaller views that I would like to dismiss with the back button, such as small information views that pop up, etc, but this is good for anyone who needs to override the behavior of the back button inside fragments.
First, define an Interface
This interface, which I call
Backable
(I'm a stickler for naming conventions), has a single methodonBackPressed()
that must return aboolean
value. We need to enforce a boolean value because we will need to know if the back button press has "absorbed" the back event. Returningtrue
means that it has, and no further action is needed, otherwise,false
says that the default back action still must take place. This interface should be it's own file (preferably in a separate package namedinterfaces
). Remember, separating your classes into packages is good practice.Second, find the top fragment
I created a method that returns the last
Fragment
object in the back stack. I use tags... if you use ID's, make the necessary changes. I have this static method in a utility class that deals with navigation states, etc... but of course, put it where it best suits you. For edification, I've put mine in a class calledNavUtils
.Make sure the back stack count is greater than 0, otherwise an
ArrayOutOfBoundsException
could be thrown at runtime. If it isn't greater than 0, return null. We'll check for a null value later...Third, Implement in a Fragment
Implement the
Backable
interface in whichever fragment where you need to override the back button behavior. Add the implementation method.In the
onBackPressed()
override, put whatever logic you need. If you want the back button to not pop the back stack (the default behavior), return true, that your back event has been absorbed. Otherwise, return false.Lastly, in your Activity...
Override the
onBackPressed()
method and add this logic to it:We get the current fragment in the back stack, then we do a null check and determine if it implements our
Backable
interface. If it does, determine if the event was absorbed. If so, we're done withonBackPressed()
and can return. Otherwise, treat it as a normal back press and call the super method.Second Option to not involve the Activity
At times, you don't want the Activity to handle this at all, and you need to handle it directly within the fragment. But who says you can't have Fragments with a back press API? Just extend your fragment to a new class.
Create an abstract class that extends Fragment and implements the
View.OnKeyListner
interface...As you can see, any fragment that extends
BackableFragment
will automatically capture back clicks using theView.OnKeyListener
interface. Just call the abstractonBackButtonPressed()
method from within the implementedonKey()
method using the standard logic to discern a back button press. If you need to register key clicks other than the back button, just be sure to call thesuper
method when overridingonKey()
in your fragment, otherwise you'll override the behavior in the abstraction.Simple to use, just extend and implement:
Since the
onBackButtonPressed()
method in the super class is abstract, once you extend you must implementonBackButtonPressed()
. It returnsvoid
because it just needs to perform an action within the fragment class, and does not need to relay the absorption of the press back to the Activity. Make sure you do call the ActivityonBackPressed()
method if whatever you're doing with the back button doesn't require handling, otherwise, the back button will be disabled... and you don't want that!Caveats As you can see, this sets the key listener to the root view of the fragment, and we'll need to focus it. If there are edit texts involved (or any other focus-stealing views) in your fragment that extends this class, (or other inner fragments or views that have the same), you'll need to handle that separately. There's a good article on extending an EditText to lose focus on a back press.
I hope someone finds this useful. Happy coding.
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 theViewPager
so that you will know when the user is in the second activity. If he is in the second activity, make a booleantrue
as follows:Now check for the boolean whenever back button is pressed and set the current item to your first Fragment:
If you use EventBus, it is probably a far more simpler solution :
and in your Activity class you can define :
BackPressedMessage.java is just a POJO object
This is super clean and there is no interface/implementation hassle.
on mainActivity
on fragment implement base activity/fragment like
DraweHomeActivity is my base activity write
and create method doBack
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:
(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:
I can confirm that this method works for me.
I solved in this way override
onBackPressed
in the Activity. All theFragmentTransaction
areaddToBackStack
before commit: