I tried to find a method in the new Navigation components but I didn\'t find anything about that.
I have the current destination with :
mainHostFrag
Based on other answers
Fragment navHostFragment = getSupportFragmentManager().getPrimaryNavigationFragment();
Fragment fragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
((Your Fragment Class) fragment).(public method inside the fragment)
worked for me
Navigation does not provide any mechanism for getting the implementation (i.e., the Fragment itself) of the current destination.
As per the Creating event callbacks to the activity, you should either communicate with your Fragment by
onAttach
method, casting your Activity to an instance of an interface you provideI post my complete answer with androidx. Care : in my case i needed to retrieve one of the child fragment (could not be the first).
In MainActivity you should have something like :
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.mytest, R.id.nav_help)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
...
Then you have to create a method to retrieve the good fragment.
private MyTestFragment getMyTestFragment(){
MyTestFragment resultFragment = null;
Fragment navHostFragment = getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
if(navHostFragment != null && navHostFragment.getChildFragmentManager() != null) {
List<Fragment> fragmentList = navHostFragment.getChildFragmentManager().getFragments();
for (Fragment fragment : fragmentList) {
if (fragment instanceof MyTest) {
resultFragment = (MyTest) fragment;
break;
}
}
}
return resultFragment;
}
Finally you get it.
@Override public void onBackPressed() { super.onBackPressed();
NavController navController = Navigation.findNavController(this, R.id.fragment);
int id=navController.getCurrentDestination().getId();
if(id==R.id.startGameFragment ){
selectedPosition(0);
}else if(id==R.id.gameFragment ){
selectedPosition(1);
}else if(id==R.id.endGameFragment ){
selectedPosition(2);
}
}enter code here
private void selectedPosition(int pos){
for (int i = 0; i >=nav_view.getMenu().size(); i++) {
nav_view.getMenu().getItem(pos).setChecked(false);
}
nav_view.getMenu().getItem(pos).setChecked(true);
}
Using Michal's answer I wrote this extension function for testing:
@Suppress("UNCHECKED_CAST")
fun <F : Fragment> AppCompatActivity.getFragment(fragmentClass: Class<F>): F? {
val navHostFragment = this.supportFragmentManager.fragments.first() as NavHostFragment
navHostFragment.childFragmentManager.fragments.forEach {
if (fragmentClass.isAssignableFrom(it.javaClass)) {
return it as F
}
}
return null
}
Used like this:
val myFragment = activity.getFragment(MyFragment::class.java)
You can do something like this:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val navHostFragment = supportFragmentManager.fragments.first() as? NavHostFragment
if(navHostFragment != null) {
val childFragments = navHostFragment.childFragmentManager.fragments
childFragments.forEach { fragment ->
fragment.onActivityResult(requestCode, resultCode, data)
}
}
}
But for more advanced communication Listeners with callback methods registered in Fragment.onAttach() (Fragment -> Activity rather one direction communication
) and SharedViewModel (bidirectional
, important to have ViewModelProviders, and Lifecycle owner that is scoped to getActivity()
rather)