15

I'm using Jetpack Navigation Components in android development (One activity, many fragments).

I want to get fragment instance of destination in OnNavigatedListener like below.

Is it possible?

class MainActivity : AppCompatActivity() {

    private lateinit var navController: NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(this, R.layout.activity_main)
        navController = Navigation.findNavController(this, R.id.nav_host_fragment)
        navController.addOnNavigatedListener { controller, destination ->
            // Here
        }
    }
}

UPDATE: The scenario

I want to get a fragment's property (or returned value from method) in activity on navigated each time.

For example,

val fragment = getFragmentInstanceFromDestination()
myActionBar.visible = fragment.getActionBarVisible()
Zain
  • 37,492
  • 7
  • 60
  • 84
naokiokada
  • 151
  • 1
  • 4
  • I don't think there is an option for this. I don't know what the scenario that want to implement, but maybe you can use viewmodel attached to your activity, and your fragments observing LiveData objects there, and from 'NavigationListener' you updating this livedata objects based on destination id, and your fragment will be notified and can 'do something'. – Alex Jun 13 '18 at 04:25
  • 1
    Based on your updated scenario, you should use ViewModel and LiveData. add to your viewmodel livedata parameter, for example 'isToolbarVisible', and observe it from your activity, from your fragments change it value, and activity will be notified. – Alex Jun 13 '18 at 06:40
  • Did you find a solution? – Viktoriia Chebotar Jul 02 '18 at 15:50

1 Answers1

1

If you are using the 1.0.0-alpha07 version, it used to be possible to do something like this:

 (destination as? FragmentNavigator.Destination)?.let { destinationClass ->
            val isNewFullscreen = destinationClass.fragmentClass.superclass == FullScreenFragment::class.java
//... adjust paddings and hide action bar, etc.

This is the approach I took for a single Activity app having two Fragment super classes, one of them is FullScreenFragment (the one you can see being used in the example), which hides action bar and navigation bar and also, NavigationFragment (the name is confusing, but this one shows the navigation bar and action bar).

The problem with this, is that you also need to adjust the padding of your default navigation fragment, as for FullScreenFragments it would occupy the entirety of the screen whereas NavigationFragment should account both for the action and navigation bar.

Now with the new 1.0.0-alpha08 the FragmentNavigatio.Destination.fragmentClass is no longer available, so I am still thinking how to solve this. I am considering using destination.id == R.id.someFullScreenFragment, it is definitely less hacky than what I have in place at the moment, but I would have to keep track of a list of ids.

Either way, it is not possible, as far as I know, to get the instance of the Fragment itself, the best you can do is infer the destination and let your single activity orchestrate views accordingly.

jpalvarezl
  • 325
  • 2
  • 8
  • Any updates on new ways to get this value the way you did before? Currently using v1.0.0 and likewise can't get the fragment needed. – John Shelley Apr 30 '19 at 20:08
  • ```navController.addOnDestinationChangedListener { _, destination, _ -> val isNewFullscreen = isFullscreen(destination.id) //... }``` So now I just check the ids, of the destinations and that's how I figure whether or not I need to go full screen mode or not. I haven't been able to look into much more detail, after the 1st stable release of the navigation arch. component. So unfortunately, I don't have any updates for you, just that I moved my implementation to be like I described in my 2nd suggestion in the original answer. – jpalvarezl May 02 '19 at 08:10