44

Problem:

In my compose page -> I have list of elements, if I press anyone I will show sub contents in same page (hide the main content and show the sub content)

If I press back button from topbar, I handle myself by own logic.

But I can't able to handle system back press.

Question :

Is there any way to override the onBackPressed() in Jetpack Compose?

My code:

 @Composable
private fun AnimationRootView() {

 //Main content list
 Column(){

 }

 //Sub content list
 Column(){

 if(detail1Clicked)
   Detail1()
if(detail2Clicked)
   Detail2()
 }
 ....
 ....
}
Ranjithkumar
  • 16,071
  • 12
  • 120
  • 159

1 Answers1

112

You can use BackHandler:

@Composable
fun TestScreen() {
    BackHandler {
        // your action
    }
}

To get the same effect as with super.onBackPressed() call, you can use enabled parameter depending on your state:

BackHandler(
    // your condition to enable handler
    enabled = isOverlayPresented
) {
    // your action to be called if back handler is enabled
    isOverlayPresented = false
}
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
  • 14
    What's the alternative for `super.onBackPressed()` to trigger the usual back press behaviour if I want to close the screen after the second back-press? – SpiralDev Apr 12 '22 at 15:12
  • 6
    @SpiralDev You can pass `BackHandler(enabled = enabled)` parameter, which you can determine depending on your state. – Phil Dukhov Apr 12 '22 at 16:41
  • 1
    I'm not able to get this to react using a `ComposeView` any ideas? – desgraci May 30 '22 at 11:31
  • 1
    @desgraci please create a separate question with a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) – Phil Dukhov May 30 '22 at 13:09
  • @SpiralDev I guess we can use navController.popBackStack() as a replacement for super.onBackPressed() – Talha Akbar Dec 13 '22 at 10:23
  • 1
    @TalhaAkbar by doing so you're guessing what action should be done, it may be correct to pop in some cases, but not in all of them - e.g. the view is topmost and you need to close the app. as as said the the second commend, you should pass `enabled = false` in case when you don't need to handle it - `enabled` parameter can be dynamically calculated with a mutable state variable – Phil Dukhov Dec 13 '22 at 13:35
  • @PhilDukhov But sometimes its much easier if it'd accept a return value of Boolean - when true, back was handled, not handled and it should perform the default action. – Miha Markic Dec 22 '22 at 10:18
  • @MihaMarkic I agree that it may be easier, but we don't have choice here - `BackHandler` is just a wrapper around "new" system API, `OnBackPressedDispatcher` – Phil Dukhov Dec 22 '22 at 14:36
  • this is amazing, COMPOSE! – user924 Mar 22 '23 at 20:03
  • @PhilDukhov Have you encountered a case where the BackHandler won't work if you background and then foreground the app? – Prudhvi May 31 '23 at 05:09
  • @Prudhvi no. I suggest you debugging it starting with `Activity.onBackPressed` – Phil Dukhov May 31 '23 at 05:58