Issue
I have three top-level destination fragments in my activity:
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.trackerFragment,
R.id.nutrientFragment,
R.id.settingsFragment
),
drawerLayout
)
Which means all these fragments will show the hamburger button instead of the normal back arrow. The problem is that I have a "Go to Nutrient" button in my App that navigates to NutrientFragment, which is a top level destination. I would like that this fragment still showed the hamburger icon when navigating with the drawer, but a normal back/up button when navigating through the "Go to Nutrient" button.
My initial idea was to pass a boolean value as an argument when navigating to NutrientFragment, and inside onCreateView(), depending on the value of the boolean, remove the hamburger icon or add the back button. But that seems a little ugly and inefficient, specially if in the future I add more destinations that could have the same problem. I also have no idea how to "remove the hamburger icon and replace with the normal back button" either. Any idea on how to implement that? All the answers that I found are either in old deprecated java code or not quite what I am looking for.
Thanks.
Solution
I managed to find a solution. I added this variable to my MainActivity:
// If true, disable drawer and enable back/up button
private var isUpButton = false
And these methods:
// Disable drawer and enable the up button
fun useUpButton() {
supportActionBar?.setHomeAsUpIndicator(
androidx.appcompat.R.drawable.abc_ic_ab_back_material
)
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
isUpButton = true
}
// Enable the drawer and disable up button
private fun useHamburgerButton() {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
isUpButton = false
}
useUpButton() replaces the hamburger icon with the default up icon, locks the drawer slider and sets isUpButton to true. I also overrode onOptionsItemsSelected:
// If isUpButton is true, and the home button is clicked, navigate up and
// enable drawer again, if false, just normal drawer behaviour
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (isUpButton && item.itemId == android.R.id.home) {
navController.navigateUp()
useHamburgerButton()
true
} else super.onOptionsItemSelected(item)
}
So if the home button (either the hamburger icon or up icon) is clicked, and isUpButton is set to true, the activity will navigate up, just like normal up behaviour, and reset the isUpButton to false, so other fragments can enjoy the drawer again.
Now all I need to do is use these methods to solve my problem: I want the NutrientFragment to show the "up button" ONLY when I navigate to it WITHOUT using the drawer. To do that I need to create an argument to the NutrientFragment destination on my nav_graph.xml:
<fragment
android:id="@+id/nutrientFragment"
android:name="com.example.elegantcalorietracker.ui.fragments.NutrientFragment"
android:label="@string/nutrients"
tools:layout="@layout/fragment_nutrient">
<action
android:id="@+id/action_nutrientFragment_to_trackerFragment"
app:destination="@id/trackerFragment" />
<argument
android:name="upButtonNeeded"
android:defaultValue="false"
app:argType="boolean" />
And add this to the onCreateView() method on NutrientFragment:
upButtonNeeded = arguments?.getBoolean("upButtonNeeded") ?: false
if (upButtonNeeded) {
(activity as MainActivity).useUpButton()
}
Now, if I have a button in another fragment that navigates to NutrientFragment, all I need to do is pass true as an argument to the navigate method:
val argument = bundleOf("upButtonNeeded" to true)
this@TrackerFragment
.findNavController()
.navigate(
R.id.action_trackerFragment_to_nutrientFragment,
argument
)
Result:
When navigating to NutrientFragment using the drawer, the hamburger icon shows normally, but when navigating to it another way, like a button, the up button shows instead:
Answered By - hahmraro

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.