Reputation: 127
The first thing that I am mentioning is, onBackpressed() is deprecated in the activity scope. And I am facing the problem of closing the drawer layout onthe back button click. I am using the jetpack navigation component. When I click to the hamburger icon, the drawer is opening. After that if I click the back button it should close drawer first then the second time should exit the app but it's not closing the drawer.Without close the drawer app exits on first-time back button clicks. Now I want such behavior that while the drawer is open, it should close first when I click the back button of the device.
I am using single activity pattern and jetpack navigation ui components. My codes are right below
// jetpack navigation with kotlin
def nav_version = "2.6.0-alpha01"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
and this is the codes in my Mainactivity.kt
class MainActivity : AppCompatActivity() {
private val binding by viewBinding(ActivityMainBinding::inflate)
lateinit var controller: NavController
lateinit var config: AppBarConfiguration
lateinit var listener: NavController.OnDestinationChangedListener
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
//set the toolbar as default action bar
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
//set the toolbar with navigation graph
val host = supportFragmentManager
.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
controller = host.navController
config = AppBarConfiguration(controller.graph, binding.drawerLayout)
setupActionBarWithNavController(controller, config)
//set navview to navcontroller
binding.navView.setupWithNavController(controller)
//nav listener
listener = NavController
.OnDestinationChangedListener { controller, destination, arguments ->}
}
override fun onSupportNavigateUp(): Boolean {
return controller.navigateUp(config) || super.onSupportNavigateUp()
}
override fun onResume() {
super.onResume()
controller.addOnDestinationChangedListener(listener)
}
override fun onPause() {
super.onPause()
controller.removeOnDestinationChangedListener(listener)
}
}
Upvotes: 4
Views: 1006
Reputation: 379
According to this I/O talk, It is recommended to enable the callback when drawer is open and disable when drawer is closed.
val callback = onBackPressedDispatcher.addCallback(this, false) {
binding.drawerLayout.closeDrawer(GravityCompat.START)
}
binding.drawerLayout.addDrawerListener(object : DrawerListener {
override fun onDrawerOpened(drawerView: View) {
callback.isEnabled = true
}
override fun onDrawerClosed(drawerView: View) {
callback.isEnabled = false
}
override fun onDrawerSlide(drawerView: View, slideOffset: Float) = Unit
override fun onDrawerStateChanged(newState: Int) = Unit
})
Here is the Offical documentation
Upvotes: 2
Reputation: 8857
At the bottom of you onCreate()
:
onBackPressedDispatcher.addCallback {
if (drawerLayout.isOpen) drawerLayout.close() else finish()
}
Upvotes: 0
Reputation: 584
Drawer can be closed programmatically by using drawer.closeDrawer(Gravity.LEFT)
or some other gravity depending on usecase.
Here is how you can handle onBackPress in your case.
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// Checking if drawer is open
if (binding.drawerLayout.isDrawerOpen(binding.navView)) {
// Close the drawer on left
binding.drawerLayout.closeDrawer(Gravity.LEFT)
} else {
// Drawer not open close the application
finish()
}
}
})
You can check how to learn more how to handle onBackPressed() Here.
onBackPressed() deprecated, What is the alternative?
Upvotes: 1