Reputation: 97
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)
Upvotes: 4
Views: 3457
Reputation: 40830
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)
}
Upvotes: 6