Search code examples
androidandroid-fragmentsandroid-activityandroid-fragmentactivityandroid-jetpack-navigation

Call a current visible NavHostFragment's method from Activity


To achieve this task, I am currently using a FragmentListner interface, but I need to use create a static method to get the instance of the fragment. To avoid this approach of static way, I am thinking if there is any better way to do it. I need to get the current visible fragment instance on the Activity and based upon that I need to call a method of that fragment.

If it is not a NavHost fragment I am getting easily the instance of fragment like this below and can call any public method from it.

    Fragment fragment = getCurrentFragment();
    if (fragment instanceof MyFragment) {
                ((MyFragment) fragment).doFragmentOperation();
      }

    private Fragment getCurrentFragment() {
       return this.getSupportFragmentManager()
            .findFragmentById(R.id.framelayout);
      }

But I am able to know which fragment is visible by addOnDestinationChangedLisnter method like below

navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
        @Override
        public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
          
            switch (destination.getId()) {
                case R.id.navigation_x:
                    Toast.makeText(this, "X fragment is visible", Toast.LENGTH_SHORT).show();
                    break;
                case R.id.navigation_y:
                    Toast.makeText(this, "Y fragment is visible", Toast.LENGTH_SHORT).show();
                    break;
                case R.id.navigation_z:
                    Toast.makeText(this, "Z fragment is visible", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    });

Here we can able to know the visible fragment by destination id, is there anything which can return us the visible fragment instance directly??


Solution

  • You can use the NavHostFragment to get the primaryNavigationFragment using its childFragmentManager.

    val navHostFragment = supportFragmentManager.findFragmentById(R.id.your_nav_host_fragment_id) as NavHostFragment
    val currentFragment = navHostFragment.childFragmentManager.primaryNavigationFragment
    

    See if this works for you!