Navigation Component automatically sets those icons.
How can I override each icon? I need to override Menu and Back buttons icon.
So, now you can navigate between the fragments, upon that you removed the fragment that you want to show the back/up button from the top hierarchy of the AppBarConfiguration
.
Assuming you've 3 fragments: home, gallery, and slideshow; and you wish to show the back button on the gallery fragment, and the normal menu button in others.
So, you'd have something like:
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_home, R.id.nav_slideshow
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
Now we need to change the icons without using addOnDestinationChangedListener
.
The icon can be changed with supportActionBar.setHomeAsUpIndicator(drawableRes)
But, actually icons need to be changed manually as this is not the default behavior of the drawer layout, and navigation components has no idea about that; so you can do that using the APIs of the drawer layout.
So, first register a listener to this icon with binding.drawerLayout.addDrawerListener(toggle)
and this requires to create the ActionBarDrawerToggle
, so save it locally in the activity, and the rest is in the code comments:
class MainActivity : AppCompatActivity() {
private var toggle: ActionBarDrawerToggle? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Intialization code is omitted....
toggle = getActionBarDrawerToggle(binding.drawerLayout, binding.appBarMain.toolbar).apply {
setToolbarNavigationClickListener {
// Back to home fragment for any hit to the back button
navController.navigate(R.id.nav_home)
}
// Intialize the icon at the app start
enableHomeBackIcon(false)
}
}
fun enableHomeBackIcon(enabled: Boolean) {
// Enable/Disable opening the drawer from the start side
toggle?.isDrawerIndicatorEnabled = !enabled
// Change the default burger icon
supportActionBar?.setHomeAsUpIndicator(
if (enabled) R.drawable.back_arrow
else R.drawable.burger
)
}
private fun getActionBarDrawerToggle(
drawerLayout: DrawerLayout,
toolbar: Toolbar
): ActionBarDrawerToggle {
toggle = ActionBarDrawerToggle(
this,
drawerLayout,
toolbar,
R.string.open,
R.string.close
)
drawerLayout.addDrawerListener(toggle!!)
toggle?.syncState()
return toggle as ActionBarDrawerToggle
}
}
And as per your requirement, instead of using addOnDestinationChangedListener
, you can utilize the drawer fragments lifecycle method; I will be using onViewCreated()
:
Home & Slideshow fragment: Disable the back button through the activity:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(requireActivity() as MainActivity).enableHomeBackIcon(false)
}
Gallery fragment: Enable the back button through the activity:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(requireActivity() as MainActivity).enableHomeBackIcon(true)
}
addOnDestinationChangedListener
– Hogan