用于解决Fragment之间的跳转,传参的问题
1添加依赖 (build.gradle):
dependencies {
def nav_version = "2.7.7" // 使用当前最新稳定版
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
}
2创建导航地图
在 res/navigation/ 文件夹下新建一个 XML 文件(如 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_graph"
app:startDestination="@id/homeFragment"> <!-- 指定入口页面 -->
<!-- 定义目标1:首页 -->
<fragment
android:id="@+id/homeFragment"
android:name="com.example.app.HomeFragment"
android:label="Home"
tools:layout="@layout/fragment_home">
<!-- 定义从homeFragment到detailFragment的动作 -->
<action
android:id="@+id/action_home_to_detail"
app:destination="@id/detailFragment" />
</fragment>
<!-- 定义目标2:详情页 -->
<fragment
android:id="@+id/detailFragment"
android:name="com.example.app.DetailFragment"
android:label="Detail"
tools:layout="@layout/fragment_detail" />
</navigation>
3设置导航宿主 (NavHostFragment):
在你的主 Activity 的布局文件 (activity_main.xml) 中,放置一个 "容器" (NavHostFragment)。
◦ 这个容器告诉 Navigation 组件:"在这个区域里显示的 Fragment,都由我来管理它们的进出和切换"。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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">
<!-- 关键!NavHostFragment容器 -->
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment" <!-- 指定实现类是NavHostFragment -->
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true" <!-- 很重要!让这个NavHost处理系统返回键 -->
app:navGraph="@navigation/nav_graph" /> <!-- 关联之前定义的导航图 -->
</FrameLayout>
4执行导航 (使用 NavController):
在 HomeFragment 中,当按钮被点击时,你需要找到 "导航仪" (NavController)。
这个导航仪知道当前在哪个位置 (NavHostFragment),也有一张地图 (nav_graph.xml)。你告诉它:"执行 action_home_to_detail 这个动作"。
Kotlin 示例 (在 Fragment 中):
class HomeFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val navController = findNavController() // 获取绑定到当前视图的NavController
binding.goToDetailButton.setOnClickListener {
// 使用导航控制器执行指定的导航动作
navController.navigate(R.id.action_home_to_detail)
}
}
}
5 传递参数 (Arguments):
在导航图中定义参数:
<fragment
android:id="@+id/detailFragment"
... >
<argument
android:name="itemId"
app:argType="integer" /> <!-- 定义需要接收一个整数参数 itemId -->
</fragment>
在发起导航时传递参数:
binding.goToDetailButton.setOnClickListener {
// 创建一个 Bundle 或使用 Safe Args (推荐,见下面概念)
val bundle = bundleOf("itemId" to 12345)
navController.navigate(R.id.action_home_to_detail, bundle)
}
在 DetailFragment 中获取参数:
val itemId = arguments?.getInt("itemId") ?: 0 // 或者使用 Safe Args