Reputation: 1164
Anywhere in a NavHostFragment
I can do findNavController().navigateUp()
Or, if in my Fragment I have a button to be used for navigation, I could do either:
editButton.setOnClickListener { v ->
v.findNavController().navigateUp()
}
or
editButton.setOnClickListener {
findNavController().navigateUp()
}
Why would I use one extension function vs the other when setting up a button click listener in a Fragment?
Upvotes: 22
Views: 32531
Reputation: 8315
Although they are not identical as suggested by the top voted answer, the performance difference should be negligible in general scenarios. However if you use the v.findNavController()
on a View
which is deeply nested down, then you should prefer Fragment
extension findNavController()
as it will perform better.
In general I don't see any reason to prefer the v.findNavController
over the Fragment
extension. following is the complete code of this method from NavHostFragment
and it only calls Navigation.findNavController
if it doesn't find the NavController
using the fragment
public static NavController findNavController(@NonNull Fragment fragment) {
Fragment findFragment = fragment;
while (findFragment != null) {
if (findFragment instanceof NavHostFragment) {
return ((NavHostFragment) findFragment).getNavController();
}
Fragment primaryNavFragment = findFragment.requireFragmentManager()
.getPrimaryNavigationFragment();
if (primaryNavFragment instanceof NavHostFragment) {
return ((NavHostFragment) primaryNavFragment).getNavController();
}
findFragment = findFragment.getParentFragment();
}
// Try looking for one associated with the view instead, if applicable
View view = fragment.getView();
if (view != null) {
return Navigation.findNavController(view);
}
throw new IllegalStateException("Fragment " + fragment
+ " does not have a NavController set");
}
Upvotes: 2
Reputation: 1117
Thank you for the Java answer, I offer a ViewBinding solution in kotlin, doing the same
// NavHostFragment.kotlin
fun findMyNavController(@NonNull fragment: Fragment): NavController {
return Navigation.findNavController(binding.root)
}
Upvotes: 4
Reputation: 1888
They are almost the same, Fragment.findNavController()
is just a handy shortcut, it actually calls Navigation.findNavController(view)
at the end. Both of them are getting the NavController
from the root view of the fragment.
// NavHostFragment.java
public static NavController findNavController(@NonNull Fragment fragment) {
....
View view = fragment.getView();
if (view != null) {
return Navigation.findNavController(view);
}
...
}
Upvotes: 19