Using Compose Navigation library, I am trying to o...
# compose
y
Using Compose Navigation library, I am trying to override
onBackPressed
to not let the user exit the app (its a launcher so that's the expected behavior). But I have not found a way to check if the current destination is the main/last destination or if back stack is empty so I dont call
super.onBackpressed
on that condition.
If I try to use
Copy code
navController.backStack.size
It tells me
NavController.getBackStack can only be called from within the same library group (groupId=androidx.navigation)
So I cannot check back stack size this way
Looks like I can just call
Copy code
navController.navigateUp()
onbackPressed without calling the super. It wont close the activity.
i
You should be using the
OnBackPressedDispatcher
and callbacks there - that's what Navigation uses already
And it lets you check whether there is any back stack added either via
BackHandler
or
NavHost:
https://developer.android.com/reference/kotlin/androidx/activity/OnBackPressedDispatcher#hasenabledcallbacks
👀 1
y
Thanks I am already reading the docs for it - I am just curious why is this better than overriding
onBackPressed
?!
Now I call
Copy code
navController.navigateUp()
and if it returns false it means I am at the end of backstack
i
I think you are approaching the problem from the wrong direction and over complicating things. Let's say you have your start destination (your launcher screen). When the user is on that screen, you don't want them to be able to hit the system back button. So inside that screen, add
BackHandler { /* do nothing */ }
. That's it.
y
I actually managed to do what I wanted easily by overriding
onNewIntent
&
onBackPressed
I assume when
navigateUp()
returns false, it means the user is on home.
I use
onNewIntent
to detect when the home button is tapped. Although its not the right way I assume, but I havent found any better ways yet. I should probably look into some source code from other launchers.
Copy code
override fun onBackPressed() {
    val onHome = !navController.navigateUp()
    if (onHome) viewModel.toggleButtons()
}

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    val onHome = !navController.navigateUp()
    if (onHome) viewModel.toggleButtons()
}
i
For one, you've now broken every
BackHandler
your app ever uses. That's a pretty good sign that you've chosen the absolutely wrong approach. For two,
navigateUp()
is also never the right thing to be calling here as that also is going to break deep linking from other apps. For three, if you ever find yourself overriding methods in your activity for a Compose app, you're most certainly not doing it the way you should be as Compose offers you the tools you need without doing that
👀 1
If you want the back button to do something particular on your home screen, use a
BackHandler
🙌 1
I.e.,
BackHandler { viewModel.toggleButtons() }
🙌 1
y
I see. Thank you. Ill try that now. I did not know it could break other stuff.
@Ian Lake Works great! Thank you so much for the help! 🙏 I removed the onBackPressed override and just added a custom function for it on the HomeScreen composable. I also changed my
onNewIntent
override to this:
Copy code
override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    onBackPressed()
}
Although you said I should not override methods in my activity but I dont know if I can even detect when the Home button is tapped in compose? Is it even possible? Although I think this method is probably not the best way for non-compose layouts as well.
i
You shouldn't be doing anything when the home button is pressed
y
But my app is a launcher. I need to do stuff when the home button is tapped.
490 Views