Как установить BottomNavigationView внутри фрагмента

У меня есть одно действие и несколько фрагментов. Я настроил свою активность с помощью NavController и навигационного графика следующим образом:

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()
}

В этом навигационном графе я позабочусь о заставке, входе в систему, фрагменте регистрации и переходе к основному фрагменту, который имеет BottomNavigationView с двумя подфрагментами.

Я сделал меню для фрагментов нижнего NavView и построил для них график, идентификатор меню совпадает с идентификатором нижнего навигационного графика.

Мой макет выглядит так:

<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>

В основном фрагменте я пытаюсь настроить нижний навигационный вид с навигационным графиком следующим образом:

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)

}

Однако я продолжаю получать это исключение:

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)

общий макет предназначен для активности, верно?

Zain 20.12.2020 00:21

Нет, общий макет — это макет основного фрагмента

TheRock 20.12.2020 00:23
2
2
1 852
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
java.lang.NullPointerException: null cannot be cast to non-null type 
androidx.navigation.fragment.NavHostFragment

Вы пытаетесь преобразовать нулевое значение в ненулевое.

null получается из оператора appCompat.supportFragmentManager.findFragmentById(R.id.nav_host_fragment_main).

Потому что supportFragmentManager используется в качестве диспетчера фрагментов, которые размещены во фрагменте. Хотя supportFragmentManager должен управлять фрагментами, размещенными в активности.

Принимая во внимание, что вместо этого следует использовать childFragmentManager для управления фрагментами, размещенными в другом фрагменте.

Итак, чтобы решить эту проблему, замените supportFragmentManager на childFragmentManager в основном классе фрагментов:

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)

}

для меня childFragmentManager получается из фрагмента, а не из appCompat

BabyishTank 12.06.2021 02:14

Другие вопросы по теме