9

My activity has bottom navigation and I would like to get the instance of one of the fragments of the navigation in the activity.

I am trying to get the instance of the com.myapp.ui.MapFragment inside the onCreate of the activity (after setContentView) by first getting an instance of the nav_host_fragment and then the instance of the com.myapp.ui.MapFragment using childFragmentManager:

val navFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
val mapFragment = navFragment!!.childFragmentManager.findFragmentById(R.id.navigation_map)

It finds the instance of navFragment but mapFragment is null.

This is the activity layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:id="@+id/twitter_activity_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="100">

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/nav_view"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation"
        android:layout_weight="90"/>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_weight="10"
        app:menu="@menu/bottom_nav_menu" />

</LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

This is the navigation layout:

<?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/mobile_navigation"
app:startDestination="@+id/navigation_map">

<fragment
    android:id="@+id/navigation_map"
    android:name="com.myapp.ui.map.MapFragment"
    android:label="@string/title_map"
    tools:layout="@layout/fragment_map" />

<fragment
    android:id="@+id/navigation_places"
    android:name="com.myapp.ui.places.PlacesContainerFragment"
    android:label="@string/title_places"
    tools:layout="@layout/fragment_places_container" />

<fragment
    android:id="@+id/navigation_profile"
    android:name="com.myapp.ui.profile.ProfileFragment"
    android:label="@string/title_profile"
    tools:layout="@layout/fragment_profile" />
</navigation>

This is the activity's onCreate:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    supportActionBar?.hide()
    setTheme(preferencesUtils.appTheme)

    setContentView(R.layout.activity_main)

    val navController = findNavController(R.id.nav_host_fragment)
    val appBarConfiguration = AppBarConfiguration(
        setOf(R.id.navigation_map, R.id.navigation_places, R.id.navigation_profile)
    )

    setupActionBarWithNavController(navController, appBarConfiguration)

    nav_view.setupWithNavController(navController)

    val navFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
    val mapFragment = navFragment!!.childFragmentManager.findFragmentById(R.id.navigation_map)
}

1 Answer 1

8

As per the FragmentNavigator documentation (the underlying API that does FragmentTransactions in NavController):

The current Fragment from FragmentNavigator's perspective can be retrieved by calling FragmentManager.getPrimaryNavigationFragment() with the FragmentManager passed to this FragmentNavigator.

val navFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
val mapFragment = navFragment!!.childFragmentManager.getPrimaryNavigationFragment()
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Ian, I did come across getPrimaryNavigationFragment however the mapFragment still comes back as null. Do I need to add the fragments in a specific way? For example in code rather that in the XML layouts?
Ended up using LiveData with a shared model like you suggested here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.