如何使用Navigation Component在Fragment中替换嵌套子Fragment?
错误原因分析
你遇到的ID does not reference a View inside this Activity错误,是因为fragmentContainer属于Main Fragment的布局视图,而非宿主Activity的布局,用requireActivity()去查找自然找不到这个ID的视图。另外你代码里两个点击事件都绑定到了同一个btnOne,这是笔误。
完整实现步骤
1. 配置基础布局与导航图
Main Fragment布局示例(main_fragment.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btn_one" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="切换到First Fragment"/> <Button android:id="@+id/btn_two" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="切换到Second Fragment"/> <!-- 子Fragment容器 --> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout>
导航图配置(nav_graph.xml)
在导航图中定义MainFragment、FirstFragment、SecondFragment,并添加MainFragment到两个子Fragment的跳转动作:
<navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/nav_graph" app:startDestination="@id/mainFragment"> <fragment android:id="@+id/mainFragment" android:name="com.example.yourpackage.MainFragment" android:label="Main Fragment"> <!-- 跳转到FirstFragment的动作 --> <action android:id="@+id/action_main_to_first" app:destination="@id/firstFragment" app:launchSingleTop="true" app:popUpTo="@id/mainFragment" app:popUpToInclusive="false"/> <!-- 跳转到SecondFragment的动作 --> <action android:id="@+id/action_main_to_second" app:destination="@id/secondFragment" app:launchSingleTop="true" app:popUpTo="@id/mainFragment" app:popUpToInclusive="false"/> </fragment> <fragment android:id="@+id/firstFragment" android:name="com.example.yourpackage.FirstFragment" android:label="First Fragment"/> <fragment android:id="@+id/secondFragment" android:name="com.example.yourpackage.SecondFragment" android:label="Second Fragment"/> </navigation>
2. Main Fragment修正代码
class MainFragment : Fragment() { private lateinit var btnOne: Button private lateinit var btnTwo: Button private lateinit var navController: NavController override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.main_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) btnOne = view.findViewById(R.id.btn_one) btnTwo = view.findViewById(R.id.btn_two) // 从当前Fragment的视图中查找容器对应的导航控制器 navController = view.findNavController(R.id.fragment_container) btnOne.setOnClickListener { // 通过导航图定义的动作ID跳转 navController.navigate(R.id.action_main_to_first) } btnTwo.setOnClickListener { navController.navigate(R.id.action_main_to_second) } } }
关键注意点
- 必须通过Fragment的
view来查找容器对应的导航控制器,而不是通过Activity。 - 用导航图中定义的action ID跳转,而非直接用Fragment ID,这样可以配置弹出栈、单例等行为,符合Navigation组件的设计规范。
内容的提问来源于stack exchange,提问作者Shakeel Aziz
相关产品推荐
相关产品推荐

