Android
Fragment
Back Button
Handle
Duplicate

Android Fragment handle back button press

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Fragments do not receive a dedicated back-button callback in the same way activities historically used onBackPressed. In modern Android, the correct approach is to use the OnBackPressedDispatcher owned by the activity and register a callback from the fragment. That keeps back handling lifecycle-aware and avoids brittle manual delegation.

Use OnBackPressedDispatcher in the Fragment

The fragment can register a callback in onViewCreated and scope it to the viewLifecycleOwner.

kotlin
1class EditorFragment : Fragment(R.layout.fragment_editor) {
2    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
3        requireActivity().onBackPressedDispatcher.addCallback(
4            viewLifecycleOwner,
5            object : OnBackPressedCallback(true) {
6                override fun handleOnBackPressed() {
7                    if (hasUnsavedChanges()) {
8                        showDiscardDialog()
9                    } else {
10                        isEnabled = false
11                        requireActivity().onBackPressedDispatcher.onBackPressed()
12                    }
13                }
14            }
15        )
16    }
17
18    private fun hasUnsavedChanges(): Boolean = true
19
20    private fun showDiscardDialog() {
21        // show dialog here
22    }
23}

This is the modern solution because the callback is automatically removed when the fragment's view lifecycle ends.

Why Not Override Back in the Activity Only

Older examples often override activity-level back handling and then search for the current fragment manually. That works, but it makes the activity responsible for fragment-specific behavior.

Modern Android encourages back handling closer to the screen that owns the logic. If one fragment needs special handling and another does not, each fragment can register its own callback without turning the activity into a routing switchboard.

Disable the Callback Before Falling Through

Notice the line:

kotlin
isEnabled = false

This matters. If your callback decides not to consume the back event and you call onBackPressed() again without disabling the callback first, you can easily recurse into the same handler.

That is one of the most common mistakes in fragment-level back handling.

Use Navigation Component When Applicable

If the app uses Jetpack Navigation, many back behaviors should flow through the navigation controller rather than custom fragment code.

kotlin
findNavController().navigateUp()

Custom interception should only be added when the fragment genuinely needs to stop or modify default back behavior, such as:

  • confirming unsaved changes
  • closing an in-fragment search mode
  • collapsing a custom panel before leaving the screen

Do not intercept back just to reproduce normal navigation.

Handle Dialogs and Child Fragments Deliberately

Some screens contain child fragments, dialog fragments, or custom UI modes. In those cases, back behavior may have layers. The general rule is still the same: the component that owns the state should own the callback.

For example, if a child fragment displays a temporary editor panel, the child should handle back by dismissing that panel before the parent fragment handles navigation away from the screen.

Test the Back Path Explicitly

Back handling often breaks when state changes are added later. A fragment may start by handling only unsaved edits, then later adds search mode, selection mode, or an in-fragment bottom sheet. Each extra state adds another possible back path.

That is why fragment back logic should be treated like real state management instead of a quick callback with one if statement. Instrumented tests or at least manual regression checks should cover:

  • normal back navigation with no special state
  • back while an in-fragment mode is active
  • back after configuration changes
  • back when the fragment is not currently visible but still on the back stack

If the behavior becomes too complex, move it into a dedicated coordinator or state holder rather than keeping all cases inside one callback body.

Common Pitfalls

  • Trying to override a nonexistent fragment-level onBackPressed API directly.
  • Routing all back behavior through the activity even when the logic belongs to a fragment.
  • Calling onBackPressed() from inside the callback without disabling the callback first.
  • Intercepting back for every fragment even when default navigation already does the right thing.
  • Registering callbacks against the fragment lifecycle instead of viewLifecycleOwner, which can leak stale view references.

Summary

  • Fragments should usually handle back through the activity's OnBackPressedDispatcher.
  • Register callbacks with viewLifecycleOwner so they follow the fragment view lifecycle.
  • Disable the callback before delegating to default back behavior.
  • Use custom interception only when the fragment truly owns special back-state logic.
  • If you use Jetpack Navigation, prefer navigateUp() for ordinary back navigation.

Course illustration
Course illustration

All Rights Reserved.