Android中如何在两个Navigation Graph间实现页面跳转
从ShowsFragment跳转到SettingsFragment的导航方案
问题背景
应用包含两个嵌套导航图,HomeFragment通过标签页切换shows_screen和movies_screen,现在需要实现从ShowsFragment到SettingsFragment的跳转,此前尝试添加action未生效。
现有导航图代码
容器导航图
<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" app:startDestination="@+id/main_graph"> <fragment android:id="@+id/HomeFragment" android:name="com.test.HomeFragment" android:label="fragment_home" tools:layout="@layout/home_fragment"> <action android:id="@+id/home_login" app:destination="@id/login_screen" app:popUpTo="@id/HomeFragment" app:popUpToInclusive="true" /> </fragment> <navigation android:id="@+id/settings_id" app:startDestination="@+id/SettingsFragment"> <fragment android:id="@+id/SettingsFragmentFragment" android:name="com.test.SettingsFragment" android:label="SettingsFragment"> <action android:id="@+id/action_topassword" app:destination="@id/password_screen" /> </fragment> <fragment android:id="@+id/password_screen" android:name="com.test.PasswordFragment" android:label="PasswordFragment" /> </navigation> </navigation>
home_navigation导航图
<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/home_navigation" app:startDestination="@+id/shows_screen"> <fragment android:id="@+id/shows_screen" android:name="com.test.ShowsFragment" android:label="ShowsFragment" tools:layout="@layout/shows_fragment"> </fragment> <fragment android:id="@+id/movies_screen" android:name="com.test.MoviesFragment" android:label="MoviesFragment" tools:layout="@layout/movies_fragment"> </fragment> </navigation>
HomeFragment标签切换代码
val controller = activity?.let { Navigation.findNavController(it, R.id.fragmentContainerView) } controller?.popBackStack(R.id.home_navigation, true) val navTabId = R.id.shows_screen controller?.navigate(navTabId)
解决方案
ShowsFragment属于嵌套的home_navigation导航图,SettingsFragment在容器导航图的settings_id子导航图中,跨嵌套导航图跳转需明确目标节点,具体步骤如下:
步骤1:在home_navigation中添加跳转action
修改home_navigation里的shows_screen片段,添加指向settings_id子导航图的action:
<fragment android:id="@+id/shows_screen" android:name="com.test.ShowsFragment" android:label="ShowsFragment" tools:layout="@layout/shows_fragment"> <!-- 添加跳转至settings导航图的action --> <action android:id="@+id/action_shows_to_settings" app:destination="@id/settings_id" <!-- 可选:清除当前home_navigation栈,避免返回时回到标签页 --> app:popUpTo="@id/home_navigation" app:popUpToInclusive="true"/> </fragment>
步骤2:确保容器导航图导入home_navigation
如果容器导航图未引用home_navigation,需添加<include>标签:
<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" app:startDestination="@+id/main_graph"> <!-- 导入home_navigation导航图 --> <include app:graph="@navigation/home_navigation" /> <!-- 原有代码保持不变 --> <fragment android:id="@+id/HomeFragment" android:name="com.test.HomeFragment" android:label="fragment_home" tools:layout="@layout/home_fragment"> <action android:id="@+id/home_login" app:destination="@id/login_screen" app:popUpTo="@id/HomeFragment" app:popUpToInclusive="true" /> </fragment> <navigation android:id="@+id/settings_id" app:startDestination="@+id/SettingsFragment"> <fragment android:id="@+id/SettingsFragmentFragment" android:name="com.test.SettingsFragment" android:label="SettingsFragment"> <action android:id="@+id/action_topassword" app:destination="@id/password_screen" /> </fragment> <fragment android:id="@+id/password_screen" android:name="com.test.PasswordFragment" android:label="PasswordFragment" /> </navigation> </navigation>
步骤3:在ShowsFragment中执行跳转
在ShowsFragment的逻辑代码中调用导航action:
// 获取当前导航控制器 val navController = Navigation.findNavController(requireView()) // 执行跳转 navController.navigate(R.id.action_shows_to_settings)
替代方案:直接跳转至SettingsFragment
若无需通过子导航图跳转,可直接指定SettingsFragment的ID(注意容器导航图中其ID为SettingsFragmentFragment):
<!-- 在shows_screen中添加action --> <action android:id="@+id/action_shows_to_settings_fragment" app:destination="@id/SettingsFragmentFragment"/>
代码中调用:
navController.navigate(R.id.action_shows_to_settings_fragment)
内容的提问来源于stack exchange,提问作者Nikitha
相关产品推荐
相关产品推荐

