Search code examples
androidnavigationfragmentbottomnavigationviewonbackpressed

Navigating to Wrong Fragment On Back Pressed


I have a Main Activity with a bottom navigation bar. This bottom navigation bar includes 3 destinations.

  • Home
  • My Routes
  • Languages

When the activity first starts, it opens at Home with HomeFragment. This HomeFragment has some buttons that might navigate to different fragments. (Still inside Home)

Lets say I went to HomeFragment -> TourFragment -> ReadyRoutesFragment (all in Home) then press back button. It works properly.

But lets say I went to HomeFragment-> TourFragment -> ReadyRoutesFragment -> pressing My Routes button in bottom navigation bar -> MyRoutesFragment (the last one is in My Routes) then press back button, instead of going back to ReadyRoutesFragment I get HomeFragment.

I use navigation component to handle the navigations, did not override any back press functions. I use the defined actions while navigating between fragments inside the same bottom navigation bar destination.

However, If I do the same thing (HomeFragment-> TourFragment -> ReadyRoutesFragment -> pressing My Routes button in bottom navigation bar -> MyRoutesFragment) but instead of pressing back button press Home button then it shows ReadyRoutesFragment.

My Main Nav Graph:

<navigation
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_navigation"
app:startDestination="@id/homeFragmentStart">

<include app:graph="@navigation/home_navigation" />

<fragment
    android:id="@id/myRoutesFragment"
    android:name="com.example.extoryapp.Main.MyRoutesPage.MyRoutesFragment"
    android:label="MyRoutesFragment" >
</fragment>

<fragment
    android:id="@id/languagesFragment"
    android:name="com.example.extoryapp.Main.LanguagesPage.LanguagesFragment"
    android:label="LanguagesFragment" />

home_navigation graph:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@id/homeFragmentStart"
app:startDestination="@id/homeFragment">

<fragment
    android:id="@+id/homeFragment"
    android:name="com.example.extoryapp.Main.HomePage.HomeFragment"
    android:label="HomeFragment" >
    <action
        android:id="@+id/action_homeFragment_to_tourFragment"
        app:destination="@id/tourFragment"/>
</fragment>

<fragment
    android:id="@+id/tourFragment"
    android:name="com.example.extoryapp.Main.InformationPages.TourFragment"
    android:label="TourFragment" >
    <action
        android:id="@+id/action_tourFragment_to_routeCreationFragment"
        app:destination="@id/routeCreationFragmentMain"/>
    <action
        android:id="@+id/action_tourFragment_to_readyRoutesFragment"
        app:destination="@id/readyRoutesFragment" />
    <action
        android:id="@+id/action_tourFragment_to_destinationFragment"
        app:destination="@id/destinationFragment" />
</fragment>
<fragment
    android:id="@+id/routeCreationFragmentMain"
    android:name="com.example.extoryapp.Main.RouteCreationPages.RouteCreationFragment"
    android:label="RouteCreationFragment" />
<fragment
    android:id="@+id/readyRoutesFragment"
    android:name="com.example.extoryapp.Main.InformationPages.ReadyRoutesFragment"
    android:label="ReadyRoutesFragment" >
    <action
        android:id="@+id/action_readyRoutesFragment_to_routeCreationFragment"
        app:destination="@id/routeCreationFragmentMain" />
</fragment>
<fragment
    android:id="@+id/destinationFragment"
    android:name="com.example.extoryapp.Main.InformationPages.DestinationFragment"
    android:label="DestinationFragment" >
    <action
        android:id="@+id/action_destinationFragment_to_imageDetailFragment"
        app:destination="@id/imageDetailFragment" />
</fragment>
<fragment
    android:id="@+id/imageDetailFragment"
    android:name="com.example.extoryapp.Main.InformationPages.ImageDetailFragment"
    android:label="ImageDetailFragment" />

Solution

  • override fun onBackPressed() {
        val mainNavigationBar=findViewById<BottomNavigationView>(R.id.mainNavigationBar)
        val mainFragmentView = supportFragmentManager.findFragmentById(R.id.mainFragmentView) as NavHostFragment
        val navController = mainFragmentView.navController
    
        if(navController.currentDestination?.label=="MyRoutesFragment" || navController.currentDestination?.label=="LanguagesFragment")
            mainNavigationBar.selectedItemId=R.id.homeFragmentStart
        else
            super.onBackPressed()
    }
    

    I added this code to my MainActivity. Instead of handling backstack, I just navigate to Home if back button is pressed in My Routes or Languages.

    This was a a solution I thought about. But if there is any other suggestions, I will be happy to listen to them.