简体   繁体   中英

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?

PS: I use NavHostFragment and Kotlin

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

And to get the id of the previous destination use: previousBackStackEntry.destination.id but as it is nullable then 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
}

you can add OnDestinationChangedListener to your NavController to track the fragment changes.

val navhostContainer = supportFragmentManager.findFragmentById(R.id.nav_host_container)
    controller = navhostContainer!!.findNavController()
    controller.addOnDestinationChangedListener(listener)

val listener = NavController.OnDestinationChangedListener{
        controller, destination, arguments ->
    println("Destination Observe: ${destination.label}")
}

When the fragment is changed, listener will be triggered.

I hope that solution helps to solve your issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM