I have one activity and few fragments. I set up my activity with NavController and navigation graph like this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navHostFragment = supportFragmentManager
.findFragmentById(R.id.nav_host_activity_main) as NavHostFragment
navController = navHostFragment.findNavController()
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp() || super.onSupportNavigateUp()
}
In this navigation graph I take care of splash screen, login, register fragment and going to main fragment which has a BottomNavigationView with two sub fragments.
I made a menu for bottomNavView fragments and made a graph for them, menu id's match with bottom nav graph id's.
My layout looks like this:
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/bottom_Navigation_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/bottom_view_nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_Navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
In main fragment I am trying to set up bottom nav view with navigation graph like this:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val appCompat = requireActivity() as AppCompatActivity
val navHostFragment = appCompat.supportFragmentManager.findFragmentById(R.id.nav_host_fragment_main) as NavHostFragment
val navController = navHostFragment.findNavController()
binding.bottomNavigationView.setupWithNavController(navController)
}
However I keep getting this exception:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ak.chatter, PID: 1937
java.lang.NullPointerException: null cannot be cast to non-null type androidx.navigation.fragment.NavHostFragment
at com.ak.chatter.ui.main.MainFragment.onViewCreated(MainFragment.kt:34)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:900)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8347)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
java.lang.NullPointerException: null cannot be cast to non-null type
androidx.navigation.fragment.NavHostFragment
You try to cast a null to a non-null.
The null is got from appCompat.supportFragmentManager.findFragmentById(R.id.nav_host_fragment_main) statement.
Because the supportFragmentManager is used as the fragment manager of fragments that are hosted by a fragment. Although the supportFragmentManager should manage fragments that are hosted by an activity.
Whereas the childFragmentManager should be used instead to manage fragments that are hosted by another fragment.
So, to solve this replace supportFragmentManager with childFragmentManager in the main fragment class:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val appCompat = requireActivity() as AppCompatActivity
val navHostFragment = appCompat.childFragmentManager.findFragmentById(R.id.nav_host_fragment_main) as NavHostFragment
val navController = navHostFragment.findNavController()
binding.bottomNavigationView.setupWithNavController(navController)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With