Search code examples
androidkotlinandroid-fragmentsandroid-architecture-navigation

How can i get name of the previous Fragment android kotlin?


I need to find out from which fragment the user switched to another fragment. I thought I should use the fragment name, but how do I get that name? Or is my method not very reliable and there are some other options?

P.S.: I use NavHostFragment and Kotlin


Solution

  • UPDATE - Nov 2021

    Instead of the headache of tracking the previous fragment with passed-in arguments, you'd use previousBackStackEntry which returns a NavBackStackEntry that is:

    the previous visible entry on the back stack or null if the back stack has less than two visible entries

    So, to get the id of the previous destination use: previousBackStackEntry?.destination?.id

    For instance, assume you've 3 fragments: fragment_a, fragment_b, and fragment_c. And at the fragment_c you need to know from which it's reached:

    To know the previous fragment in fragment_c:

    val previousFragment = findNavController().previousBackStackEntry?.destination?.id
    
    previousFragment?.let {
        when (previousFragment) {
            R.id.fragment_a_id ->
                // The previous fragment is Fragment a
    
            R.id.fragment_b_id ->
                // The previous fragment is Fragment b
    
            else ->
                // The previous fragment is neither Fragment a nor b
        }
    }
    


    Original Answer - Sep 2021

    You'd consider passing some data between destinations/fragments; for instant you would consider the passed-in data to be integers; and create constant integers for each fragment, whenever you do a navigation, then pass the constant assigned for the current fragment.

    Example:

    By using safe Args for actions & passing data during the navigation.

    Assuming we want to navigate from FragmentA to FragmentB:

    The NavGraph should have an action represents the direction and an argument to be set to the origin fragment during the navigation:

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/nav_graph"
        app:startDestination="@id/mainFragment">
    
        <fragment
            android:id="@+id/fragmentA"
            android:name="......FragmentA"
            android:label="....">
            
            
            <action
                android:id="@+id/action_fragment_a_to_fragment_b"
                app:destination="@id/fragmentB" />
                
            <argument
                android:name="previousFragment"
                android:defaultValue="-1"
                app:argType="integer" />
                
                
        </fragment>
    
    
        <fragment
            android:id="@+id/fragmentB"
            android:name="......FragmentB"
            android:label="....">
            
            <argument
                android:name="previousFragment"
                android:defaultValue="-1"
                app:argType="integer" />
                
        </fragment>
    
       
    </navigation>
    

    Create the constants that correspond to destination fragments:

    companion object {
        const val FRAGMENT_A = 101
        const val FRAGMENT_B = 102
    }
    

    And the navigation action from FragmentA to FragmentB:

    Do the navigation @FragmentA:

    findNavController().navigate(
                    FragmentADirections.actionFragmentAToFragmentB()
                        .setPreviousFragment(FRAGMENT_A)
    

    Then check that @FragmentB:

    val args: FragmentBArgs = FragmentBArgs.fromBundle(requireArguments())
    when (val previousFragment = args.previousFragment) {
        FRAGMENT_A -> {
            Log.d("LOG_TAG", "$previousFragment") // Should print 101
        }
        // Complete the rest of fragment cases
    }