I want to add custom up navigation from fragment using Navigation component
In my build.gradle(app)
I use androidx.appcompat:appcompat:1.1.0-
This set up also works and you won't need to override onSupportNavigateUp
in your activity:
NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)
toolbar.setNavigationOnClickListener {
if (navController.currentDestination?.id == R.id.destinationOfInterest) {
// Custom behavior here
} else {
NavigationUI.navigateUp(navController, configuration)
}
}
I prefer to set up the Toolbar
since it will handle automatically the up navigation and open/close a DrawerLayout
if you have one.
You need to call onBackPressed()
from onBackPressedDispatcher
property. Assuming your Toolbar is properly setup you can use the code below in your Activity.
override fun onOptionsItemSelected(menuItem : MenuItem?) : Boolean {
if (menuItem.getItemId() == android.R.id.home) {
onBackPressedDispatcher.onBackPressed()
return true // must return true to consume it here
}
return super.onOptionsItemSelected(menuItem)
}
on Fragment override
override fun onAttach(context: Context) {
super.onAttach(context)
//enable menu
setHasOptionsMenu(true)
requireActivity()
.onBackPressedDispatcher
.addCallback(this){
//true means that the callback is enabled
this.isEnabled = true
exitDialog() //dialog to conform exit
}
}
What this does is :
Trigger a call to the currently added OnBackPressedCallback callbacks in reverse order in which they were added. Only if the most false from its
OnBackPressedCallback#handleOnBackPressed()
will any previously added callback be called.
I am using AndroidX in my example therefore my import will look like
import androidx.appcompat.app.AppCompatActivity
.
Add click event to toolbar back button in this way
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// Toolbar back button pressed, do something you want
default:
return super.onOptionsItemSelected(item);
}
}
Another way
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
// Title and subtitle
toolbar.setNavigationOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Toolbar back button pressed, do something you want
}
});
I found a solution
handleOnBackPressed()
method invokes only on device's back button click.
I wonder, why neither onOptionsItemSelected()
nor onSupportNavigateUp()
methods haven't been called on pressing "up button" in toolbar. And the answer is I used
NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)
in activity to setup toolbar with navigation component. And that made toolbar responsive for work with navigation internally, pressing "up button" haven't invoked any of overridden methods in activity or fragments.
Instead should be used
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)
That will make actionBar responsive for navigation, thus I can use overridden functions onOptionsItemSelected()
and onSupportNavigateUp()
And best place (in my case) to add custom behavior on "up button" click for certain screen is
onSupportNavigateUp()
of hosted activity, like that
override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.mainNavHostFragment)
return when(navController.currentDestination?.id) {
R.id.destinationOfInterest -> {
// custom behavior here
true
}
else -> navController.navigateUp()
}
}
But worth to say, that if you want implement custom behavior directly in fragment, answer of @Enzokie should work like a charm