There’s a method called onBackPressed
that you can override in Activity
classes. This is a pretty easy way implement any custom action you might want to take if and when the user presses the back button. However, this onBackPressed
override option is unavailable in fragments. We can make this feature available in fragments however. And that’s what I’ll be going over in this post.
Our activity and fragment that we’ll be referring to as examples will be called MainActivity
and MainFragment
(creative names, I know). MainActivity
will be displaying MainFragment
and for whatever reason, we want to be able to listen to onBackPressed
in our fragment instead of our activity. Just as a note, I had come across this problem where one activity had a ViewPager
displaying content from two different fragments and I had to listen to the back pressed action in the fragments instead of the Activity
due to the requirement of passing some data from individual fragments instead of the Activity
.
To implement this, we need to utilize interfaces in our Activity which we will implement in our Fragment. So, in your MainActivity
, add an interface called OnBackPressedListener
like this and override both the onDestroy
and onBackPressed
method as shown.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class MainActivity extends AppCompatActivity { protected OnBackPressedListener onBackPressedListener; public interface OnBackPressedListener { void doBack(); } public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { this.onBackPressedListener = onBackPressedListener; } @Override protected void onDestroy() { onBackPressedListener = null; super.onDestroy(); } @Override public void onBackPressed() { if (onBackPressedListener != null) { onBackPressedListener.doBack(); } else { super.onBackPressed(); } } } |
Here, we are defining an interface called onBackPressedListener
which defines a method called doBack
. We will be implementing this interface in our fragment. We also have a method called setOnBackPressedListener
which we will be calling in our fragment.
We are also overriding both the onDestroy
methods and the onBackPressed
methods. In the onDestroy
method, we are nullifying the instantiated onBackPressedListener
so that it doesn’t interfere with any new future activities that are instantiated. In the overriden onBackPressed
method, we call the doBack
method on the onBackPressedListener
if it is not null, or just call the normal onBackPressed
method of the Activity if it is null. We’ll be utilizing this altogether in our fragment.
Now, implement our fragment like this. The main thing you’ll see is that we’ll be implementing the MainActivity’s OnBackPressedListener
in our fragment.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class MainFragment extends Fragment implements MainActivity.OnBackPressedListener { public MainFragment() { } // Some fragment related code here... @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ((MainActivity) getActivity()).setOnBackPressedListener(this); } @Override public void doBack() { // Whatever you need to do here when the user presses back } } |
The most important part in our MainFragment
is that we implement the OnBackPressedListener
interface of our MainActivity
and then in our onViewCreated
method that we override, call the setOnBackPressedListener
method while passing in the MainFragment
. This will allow us to utilize MainActivity’s onBackPressed
method in the doBack method of our MainFragment
.
And that’s how you can listen for the back pressed action within your fragments. Sometimes I do wish that Google would just provide default APIs for these types of things.