You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android导航图搭配BottomNavigationView二次跳转子Fragment加载失效求助

问题解决:嵌套导航返回后子Fragment无法加载

问题描述

我有一个配置了导航图的MainActivity,包含FragmentA与BottomNavTestFragment两个Fragment。点击FragmentA中的按钮可跳转至BottomNavTestFragment,该Fragment内部集成了BottomNavigationView,且关联了包含FragmentB和FragmentC的独立导航图。首次跳转流程正常,但从BottomNavTestFragment返回FragmentA后,再次跳转至BottomNavTestFragment时,FragmentB和FragmentC无法加载。

相关代码片段

main_navigation_graph.xml

<?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/nav_test"
    app:startDestination="@id/fragmentA">

    <fragment
        android:id="@+id/fragmentA"
        android:name="com.test.presentation.test.FragmentA"
        android:label="FragmentA"
        tools:layout="@layout/fragment_a">
        <action
            android:id="@+id/action_fragmentA_to_BNavTestFragment"
            app:destination="@id/BNavTestFragment" />
    </fragment>
    <fragment
        android:id="@+id/BNavTestFragment"
        android:name="com.test.presentation.test.BottomNavTestFragment"
        android:label="BNavTestFragment"
        tools:layout="@layout/fragment_b_nav_test" />
</navigation>

bottom_nav_graph.xml

<?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/nav_test_bottom"
    app:startDestination="@id/orderFragment">

    <fragment
        android:id="@+id/orderFragment"
        android:name="com.test.presentation.test.FragmentB"
        android:label="FragmentB"
        tools:layout="@layout/fragment_b" />

    <fragment
        android:id="@+id/profileFragment"
        android:name="com.test.presentation.test.FragmentC"
        android:label="FragmentC"
        tools:layout="@layout/fragment_c" />
</navigation>

fragment_layout_of_bottom_navigation.xml

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#E0668F">

    <!-- Fragment Container for Navigation -->
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_member_bottom_nav"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_test_bottom_view" />

    <!-- BottomNavigationView -->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:backgroundTint="@color/primary_variant"
        app:itemIconTint="@color/bottom_nav_item_color"
        app:itemTextColor="@color/bottom_nav_item_text_color"
        app:labelVisibilityMode="labeled"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_nav_menu_test" />

</androidx.constraintlayout.widget.ConstraintLayout>

menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/orderFragment"
        android:icon="@drawable/ic_bottom_menu_orders"
        android:title="@string/bt_menu_orders" />
    <item
        android:id="@+id/profileFragment"
        android:icon="@drawable/ic_bottom_menu_profile"
        android:title="@string/bt_menu_profile" />

</menu>

BottomNavFragment.kt 初始化代码

private fun setUpBottomNavigation() {
    val navHostFragment = requireActivity().supportFragmentManager
        .findFragmentById(R.id.nav_host_member_bottom_nav) as NavHostFragment
    val navController: NavController = navHostFragment.navController

    val bottomNavigationView =
        requireView().findViewById<BottomNavigationView>(R.id.bottom_navigation)
    bottomNavigationView.setupWithNavController(navController)
}

问题原因

  1. FragmentManager使用错误:用requireActivity().supportFragmentManager查找嵌套的NavHostFragment,返回后Activity的FragmentManager会保留旧的NavHost实例,再次进入时无法匹配新创建的BottomNavTestFragment的视图,导致找不到正确的NavHost。
  2. defaultNavHost属性冲突:嵌套的NavHost设置app:defaultNavHost="true"会拦截返回键,干扰主导航栈的状态,导致Fragment重建时导航逻辑混乱。
  3. 导航绑定时机问题:如果初始化逻辑没有在每次视图创建时执行,Fragment重建时无法重新绑定导航关系。

解决方案

1. 改用ChildFragmentManager查找NavHostFragment

修改BottomNavTestFragment的setUpBottomNavigation方法,使用当前Fragment的childFragmentManager而非Activity的FragmentManager:

private fun setUpBottomNavigation() {
    val navHostFragment = childFragmentManager
        .findFragmentById(R.id.nav_host_member_bottom_nav) as NavHostFragment
    val navController: NavController = navHostFragment.navController

    val bottomNavigationView =
        requireView().findViewById<BottomNavigationView>(R.id.bottom_navigation)
    bottomNavigationView.setupWithNavController(navController)
}

2. 移除嵌套NavHost的defaultNavHost属性

修改fragment_layout_of_bottom_navigation.xml中的FragmentContainerView,去掉app:defaultNavHost="true",让主导航栈处理返回逻辑:

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host_member_bottom_nav"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:navGraph="@navigation/nav_test_bottom" />

注意:修正app:navGraph指向正确的bottom_nav_graph.xml,原代码中的@navigation/nav_test_bottom_view是错误的

3. 确保每次视图创建时初始化导航

在BottomNavTestFragment的onViewCreated方法中调用初始化逻辑,保证Fragment重建时重新绑定导航:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    setUpBottomNavigation()
}

内容的提问来源于stack exchange,提问作者darwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 15:56:04